国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

最長遞增子序列問題(你真的會(huì)了嗎)

這篇具有很好參考價(jià)值的文章主要介紹了最長遞增子序列問題(你真的會(huì)了嗎)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

目錄

一.最長遞增子序列問題I

二.最長遞增子序列問題II

三. 最長遞增子序列問題III


一.最長遞增子序列問題I

1.對(duì)應(yīng)牛客網(wǎng)鏈接

最長上升子序列(一)_??皖}霸_??途W(wǎng) (nowcoder.com)

2.題目描述:

最長遞增子序列,算法,leetcode

?3.解題思路

1.首先我們分析題意:最長遞增子序列拆:要遞增的,還是序列,不一定連續(xù) ,要長度最長的。

2.子序列和子數(shù)組問題我們一般考慮必須以某個(gè)位置結(jié)尾如何如何,在本題中我們可以這樣考慮必須以i位置結(jié)尾的情況下最長遞增子序列的最大長度是多少我們每個(gè)位置都這么干那么答案一定就在其中

下面以[5,7,1,9,4,6,2,8,3]為例:

最長遞增子序列,算法,leetcode

第一個(gè)元素 5: 遞增長度只能為1, 接下來第二個(gè)7,比5大,長度為2

最長遞增子序列,算法,leetcode

?

第三個(gè)元素 1:前面沒有比它大的,只能為1 , 第四個(gè)元素9,前面有5,7,故長度為3到這里你發(fā)現(xiàn),9比7大,7往前構(gòu)成的長度是2,那9就可以接在7的后面,變成長度加一的新序列。

最長遞增子序列,算法,leetcode

最長遞增子序列,算法,leetcode

?我相信老鐵應(yīng)該懂了

4.對(duì)應(yīng)代碼:

class Solution {
  public:
    /**
     * 代碼中的類名、方法名、參數(shù)名已經(jīng)指定,請(qǐng)勿修改,直接返回方法規(guī)定的值即可
     *
     * 給定數(shù)組的最長嚴(yán)格上升子序列的長度。
     * @param arr int整型vector 給定的數(shù)組
     * @return int整型
     */
    int LIS(vector<int>& arr) {
        if (arr.empty())
            return 0;
        // write code here
        int N = arr.size();
        vector<int>dp(N, 1);//每個(gè)位置最長遞增子序列的長度至少為1自己本身就是
        //dp的含義是必須以i位置結(jié)尾的情況下最長遞增子序列的最大長度
        int maxLen = 1;
        for (int i = 1; i < N; i++) {
            for (int j = 0; j < i; j++) {
                if (arr[i] > arr[j]) {
                    dp[i] = max(dp[i], dp[j] + 1); //長度加1
                }
            }
            maxLen = max(maxLen, dp[i]);//更新最大長度
        }
        return maxLen;
    }

};

二.最長遞增子序列問題II

1.對(duì)應(yīng)??途W(wǎng)鏈接:

最長上升子序列(二)_??皖}霸_牛客網(wǎng) (nowcoder.com)

2.題目描述:

最長遞增子序列,算法,leetcode

?3.解題思路:

1.在這里我們引入end數(shù)組,end[i]的值為最目前為止長度為i+1的最小結(jié)尾

2.每次去end數(shù)組里面去找大于等于arr[i]最左的位置

最長遞增子序列,算法,leetcode

?

我們看同樣是長度為2的子序列,[2,3]就比[2,5]好。因?yàn)閇2,3]后面如果有4的話,組成[2,3,4]長度就是3了,但是[2,5]因?yàn)椴粷M足條件,就沒法組隊(duì)了。

我們組成子序列的時(shí)候,不僅要讓這個(gè)序列盡可能的長,而且要讓子序列中的上升的時(shí)候盡可能的緩慢,[2,3]就比[2,5]上升的緩慢,這樣就有機(jī)會(huì)能拼接出更長的上升子序列。我們用一個(gè)數(shù)組來保存當(dāng)前的最長上升子序列,這個(gè)數(shù)組是嚴(yán)格遞增的。
因?yàn)槭菄?yán)格遞增的,數(shù)組中最后一個(gè)值nums[max]就是最大值,如果下次再碰到一個(gè)數(shù)字n,它比num[max]還要大,那么很明顯,這個(gè)子序列的長度就要+1,并且將數(shù)組n添加到數(shù)組的末尾。

[2,3,7,8,11,13,18]是目前為止最長的上升子序列,之后如果又碰到了19,或者101,因?yàn)樗麄兌即笥跀?shù)組中的最大值18,所以直接將其添加到數(shù)組末尾就可以了,同時(shí)子序列的長度要+1。19和101的例子很好理解,但如果下次碰到的數(shù)字是6或者12呢?因?yàn)橐屪有蛄猩仙谋M可能緩慢,那么讓[2,5,7...]變成[2,5,6...]更合適,因?yàn)楹笳呱仙母徛M瑯?將[...8,11,13,18]變成[...8,11,12,18]也是上升的更緩慢一點(diǎn)。
也就是,已知上升子序列[i,i_1,i_2,....,i_n],現(xiàn)在我們?cè)诶^續(xù)遍歷的過程中碰到了一個(gè)值i_k,這個(gè)值是小于i_n的,所以上升子序列的長度還是不變。但是我們需要找到一個(gè)位置,將i_k替換掉某個(gè)舊的值。

對(duì)應(yīng)動(dòng)圖:

最長遞增子序列,算法,leetcode

4.對(duì)應(yīng)代碼:

class Solution {
  public:
    /**
     * 代碼中的類名、方法名、參數(shù)名已經(jīng)指定,請(qǐng)勿修改,直接返回方法規(guī)定的值即可
     *
     * 該數(shù)組最長嚴(yán)格上升子序列的長度
     * @param a int整型vector 給定的數(shù)組
     * @return int整型
     */
    int LIS(vector<int>& arr) {
        // write code here
        if (arr.empty()) {
            return 0;
        }
        int N = arr.size();
        vector<int>end(N);
        //end[i]的含義是目前為止長度為i+1的最小結(jié)尾
        end[0] = arr[0];
        int L = 0;
        int maxLen = 1;
        int right = 0; //用于控制end數(shù)組的范圍
        int R = right;
        for (int i = 1; i < N; i++) {
            L = 0;
            R = right;
            while (L <= R) {//用于查找大于等于arr[i]最左邊的位置
                int mid = (L + R) >> 1;
                if (arr[i] > end[mid]) {
                    L = mid + 1;
                } else {
                    R = mid - 1;
                }
            }
            right = max(right, L); //更新右邊界
            maxLen = max(maxLen, L + 1);
            end[L] = arr[i];

        }
        return maxLen;
    }
};

三. 最長遞增子序列問題III

1.對(duì)應(yīng)letecode鏈接:

最長上升子序列(三)_??皖}霸_??途W(wǎng) (nowcoder.com)

2.題目描述:

最長遞增子序列,算法,leetcode

3.解題思路

1.本題只是上題的一個(gè)升級(jí)版我們只需要定義一個(gè)變量記錄?一下最長遞增子序列的結(jié)尾位置在哪里即可,然后再依次遍歷

4.對(duì)應(yīng)代碼:

class Solution {
  public:
    /**
     * retrun the longest increasing subsequence
     * @param arr int整型vector the array
     * @return int整型vector
     */
    vector<int> LIS(vector<int>& arr) {
        // write code here
        if (arr.empty()) {
            return {};
        }
        int N = arr.size();
        vector<int>dp(N, 1);
        vector<int>end(N);
        int maxLen = 1;
        int maxIndex = 0;
        end[0] = arr[0];
        int right = 0;
        int L = 0;
        int R = right;
        for (int i = 1; i < N; i++) {
            L = 0;
            R = right;
            while (L <= R) {
                int mid = (L + R) >> 1;
                if (arr[i] > end[mid]) {
                    L = mid + 1;
                } else {
                    R = mid - 1;
                }
            }
            right = max(right, L);
            maxLen = max(maxLen, L + 1);
            end[L] = arr[i];
            dp[i] = L + 1;
            if (dp[i] >= maxLen) {//由于要求子典序最小
                maxIndex = i;
                maxLen = dp[i];
            }
        }
        vector<int>ans(maxLen);//獲取最長的遞增子序列
        for (int i = maxIndex; i >= 0; i--) {
            if (dp[i] == maxLen) {
                ans[--maxLen] = arr[i];
            }
        }
        return ans;
    }
};

思考題:如果要獲取所有遞增子序列了?文章來源地址http://www.zghlxwxcb.cn/news/detail-616478.html

#include<iostream>
#include<vector>
using namespace std;
vector<int> process(vector<int>& arr,vector<int>&dp ,int maxLen, int index) {//獲取所有最長遞增子序列
	vector<int>ans(maxLen);
	for (int i = index; i >= 0; i--) {
		if (dp[i] == maxLen) {
			ans[--maxLen] = arr[i];
		}
	}
	cout << "進(jìn)來" << endl;
	return ans;

}
int main() {
	int N;
	cin >> N;
	vector<int>arr(N);
	for (int i = 0; i < N; i++) {
		cin >> arr[i];
	}
	vector<int>dp(N, 1);
	vector<int>end(N);
	int maxLen = 1;
	int maxIndex = 0;
	end[0] = arr[0];
	int right = 0;
	int L = 0;
	int R = right;
	for (int i = 1; i < N; i++) {
		L = 0;
		R = right;
		while (L <= R) {
			int mid = (L + R) >> 1;
			if (arr[i] > end[mid]) {
				L = mid + 1;
			}
			else {
				R = mid - 1;
			}
		}
		right = max(right, L);
		maxLen = max(maxLen, L + 1);
		end[L] = arr[i];
		dp[i] = L + 1;
		if (dp[i] >= maxLen) {
			maxIndex = i;
			maxLen = dp[i];
		}
	}
	
	vector<vector<int>>ans;
	for (int i = 0; i < N; i++) {
		if (dp[i] == maxLen) {
			ans.push_back(process(arr, dp, maxLen, i));
		}
	}
	for (int i = 0; i < ans.size(); i++) {
		for (int j = 0; j < ans[0].size(); j++) {
			cout << ans[i][j] << " ";
		}
		cout << endl;
	}


	return 0;
}

到了這里,關(guān)于最長遞增子序列問題(你真的會(huì)了嗎)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • LeetCode | C++ 動(dòng)態(tài)規(guī)劃——300.最長遞增子序列、674. 最長連續(xù)遞增序列、718. 最長重復(fù)子數(shù)組

    300題目鏈接 dp 數(shù)組定義 dp[i] 表示 i 之前包括 i 的以 nums[i]結(jié)尾 的最長遞增子序列的長度 需要包含nums[i]結(jié)尾,不然在做遞增比較的時(shí)候,就沒有意義了。 遞推公式 位置 i 的最長遞增子序列 等于 j 從 0 到 i - 1各個(gè)位置的最長遞增子序列 + 1 的 最大值 if (nums[i] nums[j]) dp[i] = ma

    2024年02月16日
    瀏覽(49)
  • leetcode300. 最長遞增子序列 子序列(不連續(xù))

    https://leetcode.cn/problems/longest-increasing-subsequence/ 給你一個(gè)整數(shù)數(shù)組 nums ,找到其中最長嚴(yán)格遞增子序列的長度。 子序列 是由數(shù)組派生而來的序列,刪除(或不刪除)數(shù)組中的元素而不改變其余元素的順序。例如,[3,6,2,7] 是數(shù)組 [0,3,1,6,2,2,7] 的子序列。 LIS即最長上升子序列,指

    2024年02月14日
    瀏覽(22)
  • 算法刷題Day 52 最長遞增子序列+最長連續(xù)遞增子序列+最長重復(fù)子數(shù)組

    我自己想出來的方法,時(shí)間復(fù)雜度應(yīng)該是 O(n2) 滑動(dòng)窗口 連續(xù)的話,可以考慮用滑動(dòng)窗口 動(dòng)態(tài)規(guī)劃 貪心算法

    2024年02月14日
    瀏覽(49)
  • 【LeetCode: 673. 最長遞增子序列的個(gè)數(shù) | 動(dòng)態(tài)規(guī)劃】

    【LeetCode: 673. 最長遞增子序列的個(gè)數(shù) | 動(dòng)態(tài)規(guī)劃】

    ?? 算法題 ?? ?? 算法刷題專欄 | 面試必備算法 | 面試高頻算法 ?? ?? 越難的東西,越要努力堅(jiān)持,因?yàn)樗哂泻芨叩膬r(jià)值,算法就是這樣? ?? 作者簡介:碩風(fēng)和煒,CSDN-Java領(lǐng)域新星創(chuàng)作者??,保研|國家獎(jiǎng)學(xué)金|高中學(xué)習(xí)JAVA|大學(xué)完善JAVA開發(fā)技術(shù)棧|面試刷題|面經(jīng)八股文

    2024年02月03日
    瀏覽(22)
  • leetcode300. 最長遞增子序列(動(dòng)態(tài)規(guī)劃-java)

    leetcode300. 最長遞增子序列(動(dòng)態(tài)規(guī)劃-java)

    來源:力扣(LeetCode) 鏈接:https://leetcode.cn/problems/longest-increasing-subsequence 給你一個(gè)整數(shù)數(shù)組 nums ,找到其中最長嚴(yán)格遞增子序列的長度。 子序列 是由數(shù)組派生而來的序列,刪除(或不刪除)數(shù)組中的元素而不改變其余元素的順序。例如,[3,6,2,7] 是數(shù)組 [0,3,1,6,2,2,7] 的子序

    2024年02月15日
    瀏覽(22)
  • ( 動(dòng)態(tài)規(guī)劃) 674. 最長連續(xù)遞增序列 / 718. 最長重復(fù)子數(shù)組——【Leetcode每日一題】

    ( 動(dòng)態(tài)規(guī)劃) 674. 最長連續(xù)遞增序列 / 718. 最長重復(fù)子數(shù)組——【Leetcode每日一題】

    難度:簡單 給定一個(gè)未經(jīng)排序的整數(shù)數(shù)組,找到最長且 連續(xù)遞增的子序列 ,并返回該序列的長度。 連續(xù)遞增的子序列 可以由兩個(gè)下標(biāo) l 和 r(l r) 確定,如果對(duì)于每個(gè) l = i r ,都有 nums[i] nums[i + 1] ,那么子序列 [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]] 就是連續(xù)遞增子序列。

    2024年02月05日
    瀏覽(24)
  • 動(dòng)態(tài)規(guī)劃算法 | 最長遞增子序列

    動(dòng)態(tài)規(guī)劃算法 | 最長遞增子序列

    通過查閱相關(guān)資料 發(fā)現(xiàn)動(dòng)態(tài)規(guī)劃問題一般就是求解最值問題 。這種方法在解決一些問題時(shí)應(yīng)用比較多,比如求最長遞增子序列等。 有部分人認(rèn)為動(dòng)態(tài)規(guī)劃的核心就是:窮舉。因?yàn)橐笞钪?,肯定要把所有可行的答案窮舉出來,然后在其中找最值。 首先,筆者認(rèn)為動(dòng)態(tài)規(guī)劃中

    2024年02月06日
    瀏覽(31)
  • 貪心算法學(xué)習(xí)——最長單調(diào)遞增子序列

    貪心算法學(xué)習(xí)——最長單調(diào)遞增子序列

    目錄 ?編輯 一,題目 二,題目接口 三,解題思路和代碼 給你一個(gè)整數(shù)數(shù)組? nums ?,找到其中最長嚴(yán)格遞增子序列的長度。 子序列? 是由數(shù)組派生而來的序列,刪除(或不刪除)數(shù)組中的元素而不改變其余元素的順序。例如, [3,6,2,7] ?是數(shù)組? [0,3,1,6,2,2,7] ?的子序列。 ?

    2024年02月08日
    瀏覽(21)
  • 【動(dòng)態(tài)規(guī)劃】求最長遞增子序列問題

    【動(dòng)態(tài)規(guī)劃】求最長遞增子序列問題

    最長遞增子序列(Longest Increasing Subsequence, LIS ) 子序列:對(duì)于任意序列s,它的子序列是通過刪除其中零個(gè)或多個(gè)元素得到的另?個(gè)序列 注:剩余元素的相對(duì)順序保持不變 給定n個(gè)整數(shù)組成的序列 s [ 1... n ] s[1...n] s [ 1... n ] ,求最長遞增子序列LIS(的長度) 8 3 6 1 3 5 4 7 假設(shè)

    2024年02月03日
    瀏覽(27)
  • vue diff 前后綴+最長遞增子序列算法

    vue diff 前后綴+最長遞增子序列算法

    如上圖所示,新舊 children 擁有相同的前綴節(jié)點(diǎn)和后綴節(jié)點(diǎn) 對(duì)于前綴節(jié)點(diǎn),我們可以建立一個(gè)索引,指向新舊 children 中的第一個(gè)節(jié)點(diǎn),并逐步向后遍歷,直到遇到兩個(gè)擁有不同 key 值的節(jié)點(diǎn)為止 對(duì)于相同的后綴節(jié)點(diǎn),由于新舊 children 中節(jié)點(diǎn)的數(shù)量可能不同,所以我們需要兩個(gè)

    2024年02月13日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包