给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。
字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。
说明:
字母异位词指字母相同,但排列不同的字符串
。
不考虑答案输出的顺序。
示例 1:
输入:s: "cbaebabacd" p: "abc"输出:[0, 6]
解释: 起始索引等于 0 的子串是 "cba", 它是 "abc" 的字母异位词。 起始索引等于 6 的子串是 "bac", 它是 "abc" 的字母异位词。
示例 2:
输入:s: "abab" p: "ab"输出:[0, 1, 2]
示例 3:
输入:s: "baa" p: "aa"输出:[1]
解释: 起始索引等于 0 的子串是 "ab", 它是 "ab" 的字母异位词。 起始索引等于 1 的子串是 "ba", 它是 "ab" 的字母异位词。 起始索引等于 2 的子串是 "ab", 它是 "ab" 的字母异位词。
花了半天, 用类似滑动窗口的思想地解决了该题。思路如下:
targetObj
;有对应字段且其不大于
targetObj 对应字段的值, 则向右偏移 right 指针的位置;无对应字段
, 则将 left 的位置移到 right 字段的位置;有对应字段且大于
targetObj 对应字段的值, 则向右偏移 left 指针的位置;需要考虑的点,
字符串是否会重复
。比如 s 为 'baa', p 为 'aa'。
/*** @param {string} s* @param {string} p* @return {number[]}*/var findAnagrams = function(s, p) {const pLength = p.lengthconst initHashObj = {} // 初始化 hash 对象let hashObj = {}const targetObj = {}for (let i = 0; i < p.length; i++) {targetObj[p[i]] = typeof(targetObj[p[i]]) === 'number' ? targetObj[p[i]] + 1 : 0initHashObj[p[i]] = 0hashObj[p[i]] = 0}const result = [] // 存储结果let left = 0, right = 0while (left < s.length && right < s.length) {if (typeof(hashObj[s[right]]) === 'number' && hashObj[s[right]] <= targetObj[s[right]]) {hashObj[s[right]] = hashObj[s[right]] + 1if (right - left + 1 === pLength) result.push(left)right++} else if (typeof(hashObj[s[right]]) !== 'number') {right++left = righthashObj = JSON.parse(JSON.stringify(initHashObj))} else {hashObj[s[left]] !== initHashObj[s[left]] && (hashObj[s[left]] = hashObj[s[left]] - 1)left++}}return result};
76