SorryToPerson logo
返回
算法2026-04-16·8 分钟

算法知识库:滑动窗口算法实现

JavaScript/TypeScript 实现滑动窗口算法,如最大子数组和、最小覆盖子串等。

滑动窗口算法实现

1. 最大连续子数组和

ts
function maxSubArray(nums: number[]): number {
  let maxSum = nums[0];
  let currentSum = nums[0];

  for (let i = 1; i < nums.length; i += 1) {
    currentSum = Math.max(nums[i], currentSum + nums[i]);
    maxSum = Math.max(maxSum, currentSum);
  }

  return maxSum;
}

2. 最小覆盖子串

ts
function minWindow(s: string, t: string): string {
  const need = new Map<string, number>();
  const window = new Map<string, number>();

  for (const char of t) {
    need.set(char, (need.get(char) || 0) + 1);
  }

  let left = 0;
  let right = 0;
  let valid = 0;
  let start = 0;
  let len = Infinity;

  while (right < s.length) {
    const c = s[right];
    right += 1;

    if (need.has(c)) {
      window.set(c, (window.get(c) || 0) + 1);
      if (window.get(c) === need.get(c)) {
        valid += 1;
      }
    }

    while (valid === need.size) {
      if (right - left < len) {
        start = left;
        len = right - left;
      }

      const d = s[left];
      left += 1;

      if (need.has(d)) {
        if (window.get(d) === need.get(d)) {
          valid -= 1;
        }
        window.set(d, window.get(d)! - 1);
      }
    }
  }

  return len === Infinity ? '' : s.substr(start, len);
}

3. 无重复字符的最长子串

ts
function lengthOfLongestSubstring(s: string): number {
  const set = new Set<string>();
  let left = 0;
  let maxLength = 0;

  for (let right = 0; right < s.length; right += 1) {
    while (set.has(s[right])) {
      set.delete(s[left]);
      left += 1;
    }
    set.add(s[right]);
    maxLength = Math.max(maxLength, right - left + 1);
  }

  return maxLength;
}

4. 滑动窗口最大值

ts
function maxSlidingWindow(nums: number[], k: number): number[] {
  const result: number[] = [];
  const deque: number[] = [];

  for (let i = 0; i < nums.length; i += 1) {
    while (deque.length && nums[deque[deque.length - 1]] <= nums[i]) {
      deque.pop();
    }
    deque.push(i);

    if (deque[0] === i - k) {
      deque.shift();
    }

    if (i >= k - 1) {
      result.push(nums[deque[0]]);
    }
  }

  return result;
}

5. 实现要点

  • 维护窗口的左右边界。
  • 根据问题调整窗口收缩条件。
  • 使用双端队列优化最大值查找。
算法滑动窗口JavaScript