题目
给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。
连续递增的子序列 可以由两个下标 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
思路
本题和最长递增子序列的区别在于多了一个连续,最长连续递增子序列,同时题目要求的是要严格大于,不能取等号
动规五部曲:
- 确定dp数组和下标
dp[i]
表示以下标为i
结尾的数组的连续递增子序列长度为dp[i]
(只是以下标i
结尾,并不一定是从下标0
开始) - 确定递推公式
如果nums[i + 1] > nums[i]
,那么以i+1
为结尾的数组的连续递增的子序列长度 一定等于 以 i 为结尾的数组的连续递增的子序列长度 + 1
即:dp[i + 1] = dp[i] + 1
因为本题要求连续递增子序列,所以就只用比较nums[i + 1]
与nums[i]
,而不用去比较nums[j]
与nums[i]
- 初始化dp数组
以下标i
为结尾的数组的连续递增的子序列长度最少也应该是1,即就是nums[i]
这一个元素,所以dp[i] = 1
- 确定遍历顺序
从前往后遍历 - 举例推导dp数组
已输入nums = [1,3,5,4,7]为例,dp数组状态如下:
java代码如下:
//dp
class Solution{
public int findLengthOfLCIS(int[] nums){
int[] dp = new int[nums.length];
for(int i = 0; i < dp.length; i++){
dp[i] = 1;
}
int res = 1;
for(int i = 0; i < nums.length; i++){
if(nums[i+1] > nums[i]){
dp[i+1] = dp[i] + 1;
}
res = res > dp[i+1] ? res : dp[i+1];
}
return res;
}
}
//贪心法:只要遇到nums[i + 1] > nums[i]的情况,count就++,否则count为1,记录count的最大值就可以了,因为本题是连续,所以可以用贪心,也比较简单
class Solution {
public int findLengthOfLCIS(int[] nums){
if(nums.length == 0){
return 0;
}
int res = 1;//连续子序列长度最小也是1
int count = 1;
for(int i = 0; i < nums.length - 1; i++){//因为 i + 1即为nums.length - 1
if(nums[i+1] > nums[i]){//连续记录
count++;
} else{
count = 1;// 不连续,count从头开始
}
if(count > res) res = count;
}
return res;
}
}