Leecode674 - daily05

人人避暑走如狂,
獨有禪師不出房;
非是禪房無熱到,
爲人心靜身即涼。

心靜自然涼—— 清涼一夏

1. 題目

674. 最長連續遞增序列

給定一個未經排序的整數數組,找到最長且連續的的遞增序列。


2. 彎路

這裏我強行使用了雙指針套路,但是這裏最後在調試的時候發現快慢指針一直需要同步成長,最後的代碼就成了這個樣子。(PS:這裏也間接說明——該題不應該使用雙指針套路)

需要注意的是:

  1. 這裏的count是用來存儲數組中某一部分的連續遞增序列的臨時長度
    (PS:可能有同學會有疑問,爲什麼count 初始值爲1 ? )
    a. 因爲對於邊界條件我們已經進行判斷,所以後面無論如何(1,1,1) 或者(3,2,1),其長度至少爲1.
  2. 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. 套路的說明

雙指針 & 快慢指針 & 滑動窗口 ,這三者之間的關係別搞糊塗…

個人理解是:

雙指針:

  1. 快慢指針
  2. 滑動窗口算法;
    a. 動態滑動窗口
    b. 固定滑動窗口

這種連續序列問題, 其實也是有固定套路—— 滑動窗口,時間不早了,有時間再展開論述。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章