问题
给定一个未经排序的整数数组,找到最长且连续递增的子序列,并返回该序列的长度
连续递增的子序列可以由两个下标 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
动态规划
动规五部曲分析如下:
确定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](j是在0到i之间遍历)
- 如果
dp数组如何初始化
- 以下标
i为结尾的数组的连续递增的子序列长度最少也应该是1,即就是nums[i]这一个元素
- 以下标
确定遍历顺序
- 从递推公式上可以看出,
dp[i + 1]依赖dp[i],所以一定是从前向后遍历for (int i = 0; i < nums.length - 1; i++) {if (nums[i + 1] > nums[i]) { // 连续记录dp[i + 1] = dp[i] + 1; // 递推公式}}
- 从递推公式上可以看出,
举例推导dp数组
- 已输入
nums = [1,3,5,4,7]为例,dp数组状态如下:
- 已输入

注意这里要取dp[i]里的最大值,所以dp[2]才是结果!
class Solution {public int findLengthOfLCIS(int[] nums) {if (nums.length <= 1)return nums.length;int result = 1;int[] dp = new int[nums.length];Arrays.fill(dp, 1);for (int i = 0; i < nums.length - 1; i++) {if (nums[i + 1] > nums[i]) { // 连续记录dp[i + 1] = dp[i] + 1;}if (dp[i + 1] > result)result = dp[i + 1];}return result;}}
- 时间复杂度:O(n)
-
贪心
这道题目也可以用贪心来做,也就是遇到
nums[i + 1] > nums[i]的情况,count++,否则count为1,记录count的最大值就可以了class Solution {public int findLengthOfLCIS(int[] nums) {if (nums.length <= 1)return nums.length;int result = 1; // 连续子序列最少也是1int count = 1;for (int i = 0; i < nums.length - 1; i++) {if (nums[i + 1] > nums[i]) { // 连续记录count++;} else { // 不连续,count从头开始count = 1;}if (count > result)result = count;}return result;}}
时间复杂度:O(n)
- 空间复杂度:O(1)
