Loading......

文章背景图

Week1_Day3_LeetCode - 滑动窗口

2025-10-15
11
-
- 分钟

🧮 Week 1 · Day 3 — LeetCode Hot 100 学习笔记


📘 1. 无重复字符的最长子串(Longest Substring Without Repeating Characters)

题目描述:

给定一个字符串 s,请你找出其中不含有重复字符的 最长子串 的长度。

示例:

输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

🔹 解法:滑动窗口 + 哈希表(双指针)

思路解析:

  1. 使用两个指针 leftright 表示当前子串的窗口;

  2. 使用 cnt(哈希表)记录窗口中每个字符的出现次数;

  3. 每次右移 right 指针时,将当前字符计入哈希表;

  4. 如果发现重复字符(cnt[x] > 1),则不断右移 left,直到窗口中没有重复字符;

  5. 每次更新 ans = max(ans, right - left + 1)

实现代码:

from collections import defaultdict

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        ans = 0
        cnt = defaultdict(int)
        left = 0

        for right, x in enumerate(s):
            cnt[x] += 1
            while cnt[x] > 1:
                cnt[s[left]] -= 1
                left += 1
            ans = max(ans, right - left + 1)
        return ans

时间复杂度: O(n)
空间复杂度: O(字符集大小)


📗 2. 找到字符串中所有字母异位词(Find All Anagrams in a String)

🔗 LeetCode 438. Find All Anagrams in a String

题目描述:

给定两个字符串 sp,找到 s 中所有 p异位词 的子串,返回这些子串的起始索引。

示例:

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引 0 的子串 "cba" 是 "abc" 的异位词;
起始索引 6 的子串 "bac" 也是 "abc" 的异位词。

🔹 解法:定长滑动窗口 + 哈希表(Counter)

思路解析:

  1. Counter(p) 统计目标字符串中各字符出现次数;

  2. s 上维护一个长度为 len(p) 的滑动窗口;

  3. 每次右移窗口时:

    • 将新字符加入计数;

    • 移除窗口左侧多余字符;

  4. 若窗口内字符频次与 p 的频次相同,则记录当前起始索引。

实现代码:

from collections import Counter
from typing import List

class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        ans = []
        cnt_p = Counter(p)
        cnt_s = Counter()

        for right, c in enumerate(s):
            cnt_s[c] += 1
            left = right - len(p) + 1

            if left < 0:
                continue

            if cnt_s == cnt_p:
                ans.append(left)

            out = s[left]
            cnt_s[out] -= 1
            if cnt_s[out] == 0:
                del cnt_s[out]

        return ans

时间复杂度: O(n)
空间复杂度: O(k)


📙 3. 和为 K 的子数组(Subarray Sum Equals K)

🔗 LeetCode 560. Subarray Sum Equals K

题目描述:

给定一个整数数组 nums 和一个整数 k,请你统计并返回 该数组中和为 k 的子数组的个数

子数组是数组中元素的连续非空序列。


🔹 解法:前缀和 + 哈希表

核心思路:

  1. prefix[j] 表示前 j 个元素的前缀和;

  2. 若存在 i < j,使得 prefix[j] - prefix[i] = k
    [i, j-1] 之间的子数组和为 k

  3. 用哈希表 cnt 记录 每个前缀和出现的次数

  4. 对于当前前缀和 s,检查是否存在 s - k

实现代码:

from collections import defaultdict
from typing import List

class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        s = 0
        cnt = defaultdict(int)
        cnt[0] = 1
        ans = 0

        for x in nums:
            s += x
            ans += cnt[s - k]
            cnt[s] += 1

        return ans

时间复杂度: O(n)
空间复杂度: O(n)


🎯 总结对比

题目

思路

技术核心

时间复杂度

空间复杂度

无重复字符的最长子串

滑动窗口

哈希表 + 双指针

O(n)

O(字符集大小)

找到字符串中所有异位词

定长滑窗

Counter 计数比较

O(n)

O(k)

和为 K 的子数组

前缀和

哈希表存前缀和次数

O(n)

O(n)

评论交流