This commit is contained in:
programmercarl
2022-12-20 15:33:57 +08:00
parent 5fc31873aa
commit 77f1c528b7
15 changed files with 290 additions and 292 deletions

View File

@@ -13,15 +13,14 @@
连续递增的子序列 可以由两个下标 l 和 rl < 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 隔开。
* 输入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。
* 输入nums = [2,2,2,2,2]
* 输出1
* 解释:最长连续递增序列是 [2], 长度为1。
提示:
@@ -41,27 +40,27 @@
1. 确定dp数组dp table以及下标的含义
**dp[i]以下标i为结尾的数组的连续递增的子序列长度为dp[i]**
**dp[i]以下标i为结尾的连续递增的子序列长度为dp[i]**
注意这里的定义一定是以下标i为结尾并不是说一定以下标0为起始位置。
2. 确定递推公式
如果 nums[i + 1] > nums[i],那么以 i+1 为结尾的数组的连续递增的子序列长度 一定等于 以i为结尾的数组的连续递增的子序列长度 + 1 。
如果 nums[i] > nums[i - 1],那么以 i 为结尾的连续递增的子序列长度 一定等于 以i - 1为结尾的连续递增的子序列长度 + 1 。
dp[i + 1] = dp[i] + 1;
dp[i] = dp[i - 1] + 1;
**注意这里就体现出和[动态规划300.最长递增子序列](https://programmercarl.com/0300.最长上升子序列.html)的区别!**
因为本题要求连续递增子序列所以就必要比较nums[i + 1]与nums[i]而不用去比较nums[j]与nums[i] j是在0到i之间遍历
因为本题要求连续递增子序列所以就必要比较nums[i]与nums[i - 1]而不用去比较nums[j]与nums[i] j是在0到i之间遍历
既然不用j了那么也不用两层for循环本题一层for循环就行比较nums[i + 1] 和 nums[i]。
既然不用j了那么也不用两层for循环本题一层for循环就行比较nums[i] 和 nums[i - 1]。
这里大家要好好体会一下!
3. dp数组如何初始化
以下标i为结尾的数组的连续递增的子序列长度最少也应该是1即就是nums[i]这一个元素。
以下标i为结尾的连续递增的子序列长度最少也应该是1即就是nums[i]这一个元素。
所以dp[i]应该初始1;
@@ -72,9 +71,9 @@
本文在确定递推公式的时候也说明了为什么本题只需要一层for循环代码如下
```CPP
for (int i = 0; i < nums.size() - 1; i++) {
if (nums[i + 1] > nums[i]) { // 连续记录
dp[i + 1] = dp[i] + 1; // 递推公式
for (int i = 1; i < nums.size(); i++) {
if (nums[i] > nums[i - 1]) { // 连续记录
dp[i] = dp[i - 1] + 1;
}
}
```
@@ -96,15 +95,16 @@ public:
if (nums.size() == 0) return 0;
int result = 1;
vector<int> dp(nums.size() ,1);
for (int i = 0; i < nums.size() - 1; i++) {
if (nums[i + 1] > nums[i]) { // 连续记录
dp[i + 1] = dp[i] + 1;
for (int i = 1; i < nums.size(); i++) {
if (nums[i] > nums[i - 1]) { // 连续记录
dp[i] = dp[i - 1] + 1;
}
if (dp[i + 1] > result) result = dp[i + 1];
if (dp[i] > result) result = dp[i];
}
return result;
}
};
```
* 时间复杂度O(n)
@@ -112,7 +112,7 @@ public:
### 贪心
这道题目也可以用贪心来做也就是遇到nums[i + 1] > nums[i]的情况count就++否则count为1记录count的最大值就可以了。
这道题目也可以用贪心来做也就是遇到nums[i] > nums[i - 1]的情况count就++否则count为1记录count的最大值就可以了。
代码如下:
@@ -123,8 +123,8 @@ public:
if (nums.size() == 0) return 0;
int result = 1; // 连续子序列最少也是1
int count = 1;
for (int i = 0; i < nums.size() - 1; i++) {
if (nums[i + 1] > nums[i]) { // 连续记录
for (int i = 1; i < nums.size(); i++) {
if (nums[i] > nums[i - 1]) { // 连续记录
count++;
} else { // 不连续count从头开始
count = 1;