人人避暑走如狂,
獨有禪師不出房;
非是禪房無熱到,
爲人心靜身即涼。
心靜自然涼—— 清涼一夏
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. 固定滑動窗口
這種連續序列問題, 其實也是有固定套路—— 滑動窗口,時間不早了,有時間再展開論述。