最长递增子序列 最长连续递增序列
引言
這兩道題有很大的相似性,在這里主要的地方就是循環(huán)的設(shè)置,不僅僅適用于這兩道題,在很多類(lèi)似的題目中都可以用到,要學(xué)會(huì)相應(yīng)的方法才行;
最長(zhǎng)遞增子序列
給你一個(gè)整數(shù)數(shù)組 nums ,找到其中最長(zhǎng)嚴(yán)格遞增子序列的長(zhǎng)度。
子序列是由數(shù)組派生而來(lái)的序列,刪除(或不刪除)數(shù)組中的元素而不改變其余元素的順序。例如,[3,6,2,7] 是數(shù)組 [0,3,1,6,2,2,7] 的子序列。
示例 1:
輸入:nums = [10,9,2,5,3,7,101,18]
輸出:4
解釋:最長(zhǎng)遞增子序列是 [2,3,7,101],因此長(zhǎng)度為 4 。
示例 2:
輸入:nums = [0,1,0,3,2,3]
輸出:4
示例 3:
輸入:nums = [7,7,7,7,7,7,7]
輸出:1
提示:
1 <= nums.length <= 2500
-10^4 <= nums[i] <= 10^4
這道題要求最長(zhǎng)遞增子序列,并沒(méi)有要求連續(xù),題解:
1,dp[i]表示0~i 的最長(zhǎng)遞增子序列長(zhǎng)度
2,位置 i 的最長(zhǎng)遞增子序列為 j 從0到 i-1 各個(gè)位置的最長(zhǎng)升序子序列加 1 的最大值
則有 if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1);
這里不是要dp[i]與dp[j] + 1進(jìn)行比較,目的是要取dp[j] + 1的最大值
因?yàn)殡S著dp[i]逐漸增大,最后一定取到的是dp[j]最大值
3,對(duì)于每一個(gè) i ,對(duì)應(yīng)的dp[i]初始大小最小為1.
4,由轉(zhuǎn)移方程可以知道循環(huán)是從前到后的,j 是0~i - 1內(nèi)的范圍,所以 j 循環(huán)是內(nèi)循環(huán);
代碼如下:
class Solution { public:int lengthOfLIS(vector<int>& nums) {int n = nums.size();if (n <= 1) return n;vector<int> dp(n, 1);int ans = 0;for (int i = 0; i < n; ++i) {for (int j = 0; j < i; ++j) {if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1);}ans = max(ans, dp[i]);}return ans;} };這道題因?yàn)椴皇沁B續(xù)的,所以在循環(huán)時(shí)需要把 i 之前的所有情況都來(lái)一遍,由此找到最長(zhǎng)遞增子序列;可以理解為 j 始終就是 i 之前的位置。
最長(zhǎng)連續(xù)遞增序列
給定一個(gè)未經(jīng)排序的整數(shù)數(shù)組,找到最長(zhǎng)且連續(xù)遞增的子序列,并返回該序列的長(zhǎng)度。
連續(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ù)遞增子序列。
示例 1:
輸入:nums = [1,3,5,4,7]
輸出:3
解釋:最長(zhǎng)連續(xù)遞增序列是 [1,3,5], 長(zhǎng)度為3。
盡管 [1,3,5,7] 也是升序的子序列, 但它不是連續(xù)的,因?yàn)?5 和 7 在原數(shù)組里被 4 隔開(kāi)。
示例 2:
輸入:nums = [2,2,2,2,2]
輸出:1
解釋:最長(zhǎng)連續(xù)遞增序列是 [2], 長(zhǎng)度為1。
提示:
0 <= nums.length <= 10^4
-10^9 <= nums[i] <= 10^9
這個(gè)題和上一題唯一不同就是求的是連續(xù)的子序列,所以步驟會(huì)少一些,因?yàn)槿绻?strong>求第 i 個(gè)位置的只需要考慮前一個(gè) i - 1 位置就可以了,不像上一道需要考慮 i 之前的所有情況;
1,dp[i]表示0~i 的最長(zhǎng)連續(xù)遞增子序列長(zhǎng)度;
2,由于只需要考慮前一個(gè),所以只要 nums[i] > nums[i - 1],那么以 i為結(jié)尾的數(shù)組的連續(xù)遞增的子序列長(zhǎng)度 一定等于以 i - 1 為結(jié)尾的數(shù)組的連續(xù)遞增的子序列長(zhǎng)度 + 1
則有 if (nums[i - 1] < nums[i]) dp[i] = dp[i - 1] + 1;
3,以下標(biāo) i 為結(jié)尾的數(shù)組的連續(xù)遞增的子序列長(zhǎng)度最少也應(yīng)該是1,即就是nums[i]這一個(gè)元素,所以dp[i]應(yīng)該初始化為1
4,因?yàn)閐p[i]是由dp[i - 1] 得來(lái)的,所以遍歷順序是從前往后;
代碼如下:
class Solution { public:int findLengthOfLCIS(vector<int>& nums) {int n = nums.size();vector<int> dp(n, 1);int ans = 1;for (int i = 1; i < n; ++i) {if (nums[i - 1] < nums[i])dp[i] = dp[i - 1] + 1;ans = max(ans, dp[i]);}return ans;} };總結(jié)
這兩道題主要注意的地方就是不連續(xù)和連續(xù)的區(qū)別,有很多題目會(huì)有這兩種情況,所以如果題目讓求
不連續(xù)的,你就需要考慮 i 之前的所有情況,這就需要多寫(xiě)一個(gè) j 作為內(nèi)循環(huán)遍歷所有情況
連續(xù)的,只需要考慮前一個(gè)與 i 的關(guān)系就可以了;
總結(jié)
以上是生活随笔為你收集整理的最长递增子序列 最长连续递增序列的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 买股票的最佳时机(六种题解dp)
- 下一篇: 代码格式驼峰命名法