LeetCode674. 最長連續遞增序列
- 閱讀本文之前,需要先了解“動態規劃方法論”,這在我的文章以前有講過
連結:動態規劃方法論
- 本文之前也講過一篇文章:最長遞增子序列,這道題,閱讀本文的同時可以與“最長遞增子序列進行對比”,這樣更能對比二者的區別!
LeetCode300.最長遞增子序列 - Tomorrowland_D - 部落格園 (cnblogs.com)
- leetcode連結如下
力扣題目連結:
題目敘述
給定一個未經排序的整數陣列,找到最長且 連續遞增的子序列,並返回該序列的長度。
連續遞增的子序列 可以由兩個下標 l 和 r(l < r)確定,如果對於每個 l <= i < r,都有 nums[i] < nums[i + 1] ,那麼子序列 [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]] 就是連續遞增子序列。
示例 1:
- 輸入:nums = [1,3,5,4,7]
- 輸出:3
- 解釋:最長連續遞增序列是 [1,3,5], 長度為3。儘管 [1,3,5,7] 也是升序的子序列, 但它不是連續的,因為 5 和 7 在原陣列裡被 4 隔開。
示例 2:
- 輸入:nums = [2,2,2,2,2]
- 輸出:1
- 解釋:最長連續遞增序列是 [2], 長度為1。
提示:
- 0 <= nums.length <= 10^4
- -10^9 <= nums[i] <= 10^9
動態規劃思路講解:
- 這道題與[最長遞增子序列](LeetCode300.最長遞增子序列 - Tomorrowland_D - 部落格園 (cnblogs.com))的區別就是,最長遞增子序列是可以不連續的,而最長連續遞增序列必須要是連續的。
- 我們這道題仍然可以採用dp[i]的思想,而這裡的dp[i]與最長遞增子序列的dp[i]就差不多了,但不是完全一致
狀態變數及其含義
- 我們可以設定狀態變數dp[i],表示以nums[i]為結尾的最長連續子序列的長度
遞推公式
-
這裡我們不需要j指標,只需要將
nums[i]與nums[i-1]
作比較,判斷它們兩個是否能繼續構成連續遞增子序列,如果nums[i]<nums[i-1]
,證明nums[i]
不能與nums[i-1]
構成連續遞增子序列,所以說dp[i]=0
-
當
nums[i]>nums[i-1]
時,意味nums[i]與前面能繼續構成連續遞增子序列,所以dp[i]=dp[i-1]+1
-
故而遞推公式為:
dp[i]=0 (nums[i]<=nums[i-1]);
dp[i]=dp[i-1]+1 (nums[i]>nums[i-1])
遍歷順序
- 這題dp[i]需要由dp[i-1]來推理出來,所以說遍歷順序顯然是從前向後遍歷。
如何初始化dp陣列?
- 顯然,一開始dp陣列中的所有元素都初始化為1,因為每個元素至少都有一個最長連續遞增子序列。
舉例驗證dp陣列
- 舉例:nums = [1,3,5,4,7]
- dp[0]=1
- dp[1]=2
- dp[2]=3
- dp[3]=0
- dp[4]=2
- 透過示例1的分析,我們也可以得知我們的dp陣列是正確的
程式碼實現:
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
//全都初始化為1
vector<int> dp(nums.size(),1);
//結果至少是1
int ans=1;
for(int i=1;i<nums.size();i++){
if(nums[i]>nums[i-1]) dp[i]=dp[i-1]+1;
ans=max(ans,dp[i]);
}
return ans;
}
};