解法一
可以遍历数组。记左指针
l
l
l 为子序列起点,右指针
r
r
r 为子序列终点。初始
l
=
0
,
r
=
0
l = 0,\ r = 0
l=0, r=0。交替右移。
在递增时 r − l + 1 r - l + 1 r−l+1 即为已递增的长度,然后与以往递增子序列的长度比较取大。
非递增时令 l = r l = r l=r。
class Solution {
public int findLengthOfLCIS(int[] nums) {
int l = 0; // 起点
int r = 0; // 终点
int maxLen = 0; // 待返回的最长长度
while (r < nums.length)
if (r == l || nums[r - 1] < nums[r]) { // 保持递增
maxLen = Math.max(maxLen, r - l + 1); // 比较取大
r++; // 终点前进
} else // 递增中断
l = r; // 更新起点
return maxLen;
}
}
你可能首先想到的是在递增中断处更新 maxLen
,这也是可行的。但递增中断除了因为 nums[r-1] >= nums[r]
外,还要考虑
r
r
r 抵达右边界。如果你经验足够,大概也会和我一样喜欢这种即时更新的方式。
解法二
class Solution {
public int findLengthOfLCIS(int[] nums) {
int l = 0;
int maxLen = 0;
for (int r = 0; r < nums.length; r++) { // 枚举 r
// 在非递增时立即更新 l
if (r > 0 && nums[r - 1] >= nums[r])
l = r;
// 即时比较取大
maxLen = Math.max(maxLen, r - l + 1);
}
return maxLen;
}
}
这种代码模式在双指针同向交替移动(不定长滑动窗口)中较为常见。
复杂度
时间:
Θ
(
n
)
\Theta(n)
Θ(n)
空间:
Θ
(
1
)
\Theta(1)
Θ(1)
推广
以下均为个人所著,兼顾了面试、本科、硕士阶段,包含清晰的 PPT 动画展示以及配套的练习题。读者也在陆续写其他算法教程。