JavaScript:leetcode_209. 長度最小的子數組(滑動窗口 + 雙指針)

題目說明

給定一個含有 n 個正整數的數組和一個正整數 s ,找出該數組中滿足其和 ≥ s 的長度最小的連續子數組,並返回其長度。如果不存在符合條件的連續子數組,返回 0。

 

示例:

輸入:s = 7, nums = [2,3,1,2,4,3]
輸出:2
解釋:子數組 [4,3] 是該條件下的長度最小的連續子數組。
 

進階:

如果你已經完成了 O(n) 時間複雜度的解法, 請嘗試 O(n log n) 時間複雜度的解法。

解題思路一

  1. 第一種方法,比較常規,符合我們的腦回路。
  2. 遍歷數組,求遍歷過的和sum。
  3. 當sum >= s時,依次減去sum前面的數字,並判斷是否依舊符合sum >= s。
  4. 直到sum >= s不成立,記錄start–到end的長度。
  5. 繼續遍歷數組的下一位,循環2-3步驟,比較之後取最小長度。

代碼實現一

/**
 * @param {number} s
 * @param {number[]} nums
 * @return {number}
 */
var minSubArrayLen = function(s, nums) {
    let sum = 0;
    let start = 0;
    let end = 0;
    let min = nums.length + 1;
    for(let i = 0; i < nums.length; i++) {
        sum += nums[i];
        if (sum >= s) {
            end = i;
            while(sum >= s) {
                sum -= nums[start++];
            }
            start--;
            sum += nums[start];
            if (min > (end - start)) {
                min = end - start + 1;
            }
        }
    }
    if (min > nums.length) {
        return 0;
    }
    return min;
};

解題思路二(雙指針)

  1. 先求出nums數組中第一次符合條件的情況。也就是看nums的前多少位>=s。記錄start,end。
  2. start,end即爲我們的雙指針,分別代表子序列的開頭和結尾。
  3. 如果sum >= s, 我們就右移動start,求最小長度。
  4. 如果sum < s, 我們就右移動end,求符合條件的情況。
  5. 直到end到達nums的尾部結束。

代碼實現二

/**
 * @param {number} s
 * @param {number[]} nums
 * @return {number}
 */
var minSubArrayLen = function(s, nums) {
    let sum = 0;
    let start = 0;
    let end = 0;
    let min = nums.length + 1;
    while (sum < s) {
        sum += nums[end++];
    }
    min = Math.min(end - start, min);
    while(end <= nums.length) {
        if (sum >= s) {
            sum -= nums[start++];
             if (sum >= s) {
                min = Math.min(end - start, min);
            }
        } else {
            sum += nums[end++];
        }
    }
    if (min > nums.length) {
        return 0;
    }
    return min;
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章