人人避暑走如狂,
独有禅师不出房;
非是禅房无热到,
为人心静身即凉。
心静自然凉—— 清凉一夏
1. 题目
给定一个未经排序的整数数组,找到最长且连续的的递增序列。
2. 弯路
这里我强行使用了双指针套路,但是这里最后在调试的时候发现快慢指针一直需要同步成长,最后的代码就成了这个样子。(PS:这里也间接说明——该题不应该使用双指针套路)
需要注意的是:
- 这里的count是用来存储数组中某一部分的连续递增序列的临时长度。
(PS:可能有同学会有疑问,为什么count 初始值为1 ? )
a. 因为对于边界条件我们已经进行判断,所以后面无论如何(1,1,1) 或者(3,2,1),其长度至少为1.- ans : 题目中要求的是最长的,所以在每次循环时,都要和 临时长度(count) 进行比对校验。
a. 这里思考一下:每次循环都需要进行比较吗?
2.1 版本一
public int findLengthOfLCIS(int[] nums) {
if(nums == null) return 0;
if(nums.length < 2) return nums.length;
int low = 0;
int fast = 1;
int ans = 1;
// 临时长度
int count = 1;
while(fast < nums.length){
if(nums[fast]>nums[low]){
count ++;
}else{
// 遇到不满足条件的,需要立刻恢复
count = 1;
}
fast++;
low ++;
// 校验最长结果
ans = ans > count ? ans : count;
}
return ans;
}
2.2 版本二
经过上面的思考,修改了ans 与 current的比较位置。(只有在条件发生变化时才有必要比较)
代码是不是更优雅了些呢?
public int findLengthOfLCIS(int[] nums) {
if(nums.length <= 1)
return nums.length;
int ans = 1;
// 当前窗口的大小
int current = 1;
for(int i=0;i < nums.length-1;i++) {
if(nums[i+1] > nums[i]) {
current++;
ans = current > ans ? current : ans;
} else {
current = 1;
}
}
return ans;
}
有没有更好的写法呢?有些 强迫症患者 就是不希望看到current的临时变量…
3. 便于理解的写法(仁者见仁)
滑动窗口算法(Sliding Window)
窗口的大小由其左右边界(left,right)计算得出
public int findLengthOfLCIS(int[] nums) {
if (nums == null) return 0;
if (nums.length < 2) return nums.length;
int left = 0;
int right = 1;
int ans = 1;
while (right < nums.length) {
if(nums[fast] > nums[fast-1]){
ans = Math.max(right-left+1,ans);
}else {
left = right;
}
right++;
}
return ans;
}
3. 套路的说明
双指针 & 快慢指针 & 滑动窗口 ,这三者之间的关系别搞糊涂…
个人理解是:
双指针:
- 快慢指针
- 滑动窗口算法;
a. 动态滑动窗口
b. 固定滑动窗口
这种连续序列问题, 其实也是有固定套路—— 滑动窗口,时间不早了,有时间再展开论述。