其他分享
首页 > 其他分享> > leetcode438_找到字符串中所有字母异位词

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

作者:互联网

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

image

方法一:简单滑动窗口

满足异位词条件:

(1)s中子串s' 与 目标字符串p的长度相等

(2)s'与p中字母相同(对排列方式没有要求)

算法思路:在字符串s中构造一个长度与字符串p的长度相同的滑动窗口截取子串s‘,并在窗口中维护每种字母的数量。当s'的每种字母数量与目标串p的每种字母数量相同,则说明当前窗口为字符串p的异位词。

技巧:可以使用数组记录字符串每种字母的个数,最后比较s'与p的记录数组即可。

public List<Integer> findAnagrams(String s, String p) {
    int[] pCount = new int[26];
    List<Integer> result = new ArrayList<>();
    int sLength = s.length();
    int pLength = p.length();
    if (sLength < pLength) {
        return result;
    }

    for (int i = 0; i < pLength; i++) {
        ++pCount[p.charAt(i) - 'a'];
    }
    int lo = 0;
    int hi = pLength;
    // [lo,hi)
    while (hi <= sLength) {
        int[] sCount = new int[26];
        int x = lo;
        for (int i = lo; i < hi; i++) {
            ++sCount[s.charAt(i) - 'a'];
        }
        if (Arrays.equals(sCount, pCount)) {
            result.add(x);
        }
        // 滑动窗口
        hi++;
        lo++;
    }
    return result;
}

方法二 :改进滑动窗口

​ 方法一中每次都需要对子串s' 进行重新统计,然后再一一比较。可以每次仅仅考虑lo收缩减少的那个字母以及hi扩张增加的字母。使用diff表示当前存在的数量不同的字母种数

 public List<Integer> findAnagrams(String s, String p) {
        int[] count = new int[26];
        List<Integer> result = new ArrayList<>();
        int sLength = s.length();
        int pLength = p.length();
        if (sLength < pLength) {
            return result;
        }

        for (int i = 0; i < pLength; i++) {
            --count[p.charAt(i) - 'a'];
            ++count[s.charAt(i) - 'a'];
        }
        //指示子串s'与字符串中不同字母的种数
        int diff = 0;
        for (int i = 0; i < 26; i++) {
            if (count[i] != 0) {
                diff++;
            }
        }
        if (diff == 0) {
            result.add(0);
        }
        int lo = 0;

        for (; lo < sLength - pLength; ) {
            // 出lo
            char ch = s.charAt(lo);
            if (count[ch - 'a'] == 0) {
                diff++;
            } else if (count[ch - 'a'] == 1) {
                diff--;
            }
            --count[ch - 'a'];
            char ch1 = s.charAt(lo + pLength);
            if (count[ch1 - 'a'] == -1) {
                diff--;
            } else if (count[ch1 - 'a'] == 0) {
                diff++;
            }
            ++count[ch1 - 'a'];
            lo++;
            if (diff == 0) {
                result.add(lo);
            }
        }
        // [lo,hi)
        return result;
    }

标签:count,pLength,leetcode438,int,异位,++,lo,字符串,diff
来源: https://www.cnblogs.com/k-young/p/16585295.html