webVueBlog / LeetCode-HOT-100

力扣 (LeetCode) 🔥LeetCode HOT 100

Home Page:https://webvueblog.github.io/LeetCode-HOT-100/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

438. 找到字符串中所有字母异位词

webVueBlog opened this issue · comments

438. 找到字符串中所有字母异位词

Description

Difficulty: 中等

Related Topics: 哈希表, 字符串, 滑动窗口

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

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

示例 1:

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

** 示例 2:**

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

提示:

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

Solution

Language: JavaScript

/**
 * @param {string} s
 * @param {string} p
 * @return {number[]}
 */
// 思路:用滑动窗口的思路,遍历字符串,
// 判断进入窗口的字符是否是需要的字符,并且加入窗口之后该字符的数量是否是和need中的字符数量一致
// 判断出窗口的字符是否是需要的字符,并且该字符在窗口中的数量是否和need中的字符数量一致
// 判断窗口中和need中符合要求的字符是否一致 如果一致 则这个窗口形成的子串就是一个异位词
// 复杂度:时间复杂度O(n),n是字符串的长度。空间复杂度O(k),k是字符集的空间

var findAnagrams = function (s, p) {
    let need = {};//需要的字符
    let win = {};//窗口中的字符
    for (let a of p) {//统计异位词的数量
        need[a] = (need[a] || 0) + 1;
    }
    //左右指针
    let left = 0,
        right = 0;
    let val = 0;//窗口中和need中字符数量一致的字符种类
    let res = [];
    while (right < s.length) {
        let c = s[right];
        right++;//右边的字符进入窗口
        if (need[c]) {
            win[c] = (win[c] || 0) + 1;//当前字符在need中,更新窗口中的字符数量
            if (win[c] == need[c]) {
                val++;//该字符在窗口中和need中的字符匹配时,字符种类+1
            }
        }
        while (right - left >= p.length) {//不断出窗口
            if (val == Object.keys(need).length) {//如果此时窗口中的子串和p是异位词则将左边界加入res中
                res.push(left);
            }
            let d = s[left];
            left++;//出窗口
            if (need[d]) {//如果该字符在need中 更新窗口中的字符数量 和字符种类
                if (win[d] == need[d]) {
                    val--;
                }
                win[d]--;
            }
        }
    }
    return res;
};