「这是我参与2022首次更文挑战的第21天,活动详情查看:2022首次更文挑战」
题目
给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。
连续递增的子序列 可以由两个下标 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.最长递增子序列的变种题目,只是加了递增的限制条件,其方法和思路也大致相同,都是使用动态规划,只是递推公式有所不同。
- dp[i]的定义
dp[i]表示前i个数中选择第i数做末端的最长连续递增子序列长度
- 状态转移方程
前i个数中选择第i数做末端的最长递增子序列等于前一个位置的dp值加一(前提条件是nums[i] > nums[i-1])。
所以递推公式为:if(nums[i] > nums[i - 1]){ dp[i] = dp[i-1] + 1;};
所以我们可以注意得到,加了限制条件后,其题目难度是小于LeetCode300.最长递增子序列递推公式非常的明了。
- dp[i]的初始化
每一个i,其对应的dp[i](即前i个数中第i数做末端的最长递增子序列长度)起始大小至少都是1,因为都会选择自己作为序列的末端。
- 确定遍历顺序
dp[i] 是第i-1处最长递增升序子序列长度推导而来,那么遍历i一定是从前向后遍历。
因此我们可以在更新dp值的时候,对比比较,以此记录最长的递增子序列长度
var findLengthOfLCIS = function(nums) {
let len = nums.length;
let res = 1;
let dp = new Array(len).fill(1);
for (let i = 1; i < len; i++){
if(nums[i] > nums[i - 1]){
dp[i] = dp[i-1] + 1;
}
res = Math.max(res,dp[i])
}
return res;
};