线性dp:LeetCode674. 最长连续递增序列

Tomorrowland 2024-08-25 08:09:09 阅读 79

LeetCode674. 最长连续递增序列

    <li>阅读本文之前,需要先了解“动态规划方法论”,这在我的文章以前有讲过

链接:动态规划方法论

  • 本文之前也讲过一篇文章:最长递增子序列,这道题,阅读本文的同时可以与“最长递增子序列进行对比”,这样更能对比二者的区别!

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;

}

};



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。