LeetCode Hot 100 (3) 滑动窗口

1/3/2024 LeetCode

# 3.无重复字符的最长子串 (opens new window)

题目:

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

示例 1:

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

示例 2:

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

示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
1
2
3
4

提示:

  • 0 <= s.length <= 5 * 104
  • s 由英文字母、数字、符号和空格组成

思路:

窗口右侧向右移动的同时,判断窗口内的值是否符合要求,不符合要求的话窗口左侧向右移动直到符合要求,在这个过程中求得结果。注意s 由英文字母、数字、符号和空格组成。

代码:

C++代码

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        vector<int> sum(300);
        int res = 0;
        for(int i=0,j=0;i<s.size();i++) {
            while(sum[s[i]]==1) {
                sum[s[j]]--;
                j++;
            }
            sum[s[i]]++;
            res = max(res,i-j+1);
        }
        return res;
    }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Go代码

func lengthOfLongestSubstring(s string) int {
    res := 0
    sum := make([]int,300)
    for i,j:=0,0;i<len(s);i++ {
        for sum[s[i]]==1 {
            sum[s[j]]--
            j++
        }
        sum[s[i]]++
        res = max(res,i-j+1)
    }
    return res
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 438.找到字符串中所有字母异位词 (opens new window)

题目:

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。

示例 1:

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
1
2
3
4
5

示例 2:

输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。
1
2
3
4
5
6

提示:

  • 1 <= s.length, p.length <= 3 * 104
  • s 和 p 仅包含小写字母

思路:

用一个长为26的数组记录长度和p一样的s中的每个字符的数量,滑动的过程中去掉左侧多余的字符,然后比较两个数组的数值是否相同,相同则符合条件记录下来。

代码:

C++代码

class Solution {
public:
vector<int> findAnagrams(string s, string p) {
    vector<int> sum_s(26);
    vector<int> sum_p(26);
    for(int i=0;i<p.size();i++) {
        sum_p[p[i]-'a']++;
    }
    int n = p.size();
    vector<int> res;
    for(int i=0;i<s.size();i++) {
        sum_s[s[i]-'a']++;
        if(i>=n) {
            sum_s[s[i-n]-'a']--;
        }
        if(sum_s==sum_p) res.push_back(i-n+1);
    }
    return res;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Go代码

func findAnagrams(s string, p string) []int {
    sum1 := make([]int,26);
    sum2 := make([]int,26);
    res := make([]int,0)
    for i:=0;i<len(p);i++ {
        sum2[p[i]-'a']++
    }
    for i:=0;i<len(s);i++ {
        sum1[s[i]-'a']++
        if i>=len(p) {
            sum1[s[i-len(p)]-'a']--
        }
        flag := true
        for j:=0;j<26;j++ {
            if sum1[j]!=sum2[j] {
                flag = false
                break
            }
        }
        if flag {
            res = append(res,i-len(p)+1)
        }
    }
    return res
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25