leetcode 力扣 438 找到字符串中所有字母异位词

179 阅读1分钟

滑动数组

如何在面试时快速想出思路?

  • 最重要的:Arrays.equals(sCount, pCount)
  • 使用两个数组,一个窗口数组sCount,保存滑动时窗口里的字母。另一个是比较数组pCount,也就是p
  • sCountint数组,指针在s上滑动时,将所指字母映射到数组下标,并++
  • pCount也是int数组,保存p的字母,在整个算法过程保持不变,唯一的作用是与sCount比较是否相同。

如何滑动?

  • 由于滑动时需要丢弃窗口的第一个字母,并加入下一个字母,因此需要分两次for循环。第一次下标为0作为窗口首字母;第二次丢弃0,下标为1作为窗口首字母。

如何快速确定丢弃的字母区间和加入的字母区间?

  • 写代码时,想象一个容量为3的窗口,如下图,并放在s的最后,窗口前的字母都是丢弃区间,也就是i = [0, sLen - pLen)
  • 挪到下标为1起始的窗口(此时i0,因为要丢弃0),窗口第三个字母到s最后一个字母都是加入区间,也就是i + pLen

1.jpeg

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        int sLen = s.length();
        int pLen = p.length();
        List<Integer> res = new ArrayList<>();

        if (sLen < pLen) {
            return res;
        }

        int[] sCount = new int[26];
        int[] pCount = new int[26];
        char[] sArray = s.toCharArray();
        char[] pArray = p.toCharArray();

        for (int i = 0; i < pLen; i++) {
            ++sCount[sArray[i] - 'a'];
            ++pCount[pArray[i] - 'a'];
        }
        if (Arrays.equals(sCount, pCount)) {
            res.add(0);
        }

        for (int i = 0; i < sLen - pLen; i++) {
            --sCount[sArray[i] - 'a'];
            ++sCount[sArray[i + pLen] - 'a'];

            if (Arrays.equals(sCount, pCount)) {
                res.add(i + 1);
            }
        }

        return res;
    }
}

2.jpeg

3.jpeg

4.jpeg

5.jpeg

6.jpeg

7.jpeg

8.jpeg

9.jpeg