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

异位词 指字母相同,但排列不同的字符串。

image.png

*思路

  1. left,right指针都s开头,用Map保存p字母的个数。
  2. 移动right指针,若字母是p中存在的字母则保存进window,当指针移动的个数等于p了,就开始比较

若window的size等于p则 它们一定是异位词。然后继续移动left指针,挨个挨个比较

  1. let s = "cbaebabacd", p = "abc"
  2. var findAnagrams = function (s, p) {
  3. const res = []
  4. const need = new Map()
  5. for (let i = 0; i < p.length; i++) {
  6. need.set(p[i], need.has(p[i]) ? need.get(p[i]) + 1 : 1)
  7. console.log(need, i);
  8. }
  9. let left = 0, right = 0, valid = 0
  10. const window = new Map()
  11. while (right < s.length) {
  12. const c = s[right]
  13. right++
  14. if (need.has(c)) {
  15. //如果c是p中存在的的字符
  16. window.set(c, window.has(c) ? window.get(c) + 1 : 1)
  17. // 当窗口中的字符数和滑动窗口中的字符数一致
  18. if (window.get(c) === need.get(c)) {
  19. // 有效字符自增
  20. valid++
  21. }
  22. }
  23. console.log(right, valid);
  24. // 当滑动窗口的大小超出p串长度时 收缩窗口
  25. while (right - left >= p.length) {
  26. // 有效字符和所需字符数一致 找到一条符合条件的子串
  27. if (valid === need.size) {
  28. res.push(left)
  29. }
  30. const d = s[left]
  31. left++
  32. console.log(left, right, c, d);
  33. // 如果离开窗口字符是所需字符
  34. if (need.has(d)) {
  35. // 如果离开字符数和所需字符数一致
  36. if (window.get(d) === need.get(d)) {
  37. // 有效字符减少一个
  38. valid--
  39. }
  40. // 更新滑动窗口中的字符数
  41. window.set(d, window.get(d) - 1)
  42. }
  43. }
  44. }
  45. return res