题目链接:
给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。
连续递增的子序列 可以由两个下标 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。
提示:
-
1 <= nums.length <= 104
-
-109 <= nums[i] <= 109
解题思路
本题与
-
如果不连续,则位置
i
的最长升序子序列与0
到i-1
的状态有关。
-
如果连续,则位置
i
的最长(连续)升序子序列只与i-1
的状态有关。
本题可以有贪心和动态规划两种解法。详细在代码注释中。
C++
// 贪心 class Solution { public: int findLengthOfLCIS(vector<int>& nums) { int count = 1; int result = 1; for (int i = 1; i < nums.size(); i++) { if (nums[i] > nums[i - 1]) { count++; } else { count = 1; } if (count > result) { result = count; } } return result; } }; // 动态规划 class Solution1 { public: int findLengthOfLCIS(vector<int>& nums) { // 1、dp数组的含义:dp[i] 下标为i结尾的数组的连续递增的子序列长度。 // 3、初始化:以下标i为结尾的数组的连续递增的子序列长度最少也应该是1,即就是nums[i]这一个元素。 vector<int> dp(nums.size(), 1); int result = 1; // 用于记录最长子序列的长度 // 4. 遍历顺序:从前向后 for (int i = 1; i < nums.size(); i++) { if (nums[i] > nums[i - 1]) { // 2. 递推公式:位置i的最长升序子序列只与位置i-1有关。 // 如果 nums[i] > nums[i - 1],那么以 i 为结尾的数组的连续递增的子序列长度 一定等于 以i-1为结尾的数组的连续递增的子序列长度 + 1。 dp[i] = dp[i - 1] + 1; } result = dp[i] > result ? dp[i] : result; } return result; } };
JavaScript
/** * @param {number[]} nums * @return {number} */ // 动态规划 var findLengthOfLCIS = function(nums) { const dp = Array(nums.length).fill(1); let result = 1; for (let i = 1; i < nums.length; i++) { if (nums[i] > nums[i - 1]) { dp[i] = dp[i - 1] + 1; } result = result > dp[i] ? result : dp[i]; } return result; };
-
时间复杂度:贪心(O(N)),动态规划(O(N))
-