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

438. 找到字符串中所有字母异位词 - 力扣(LeetCode)

java 复制代码
class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        int sLen = s.length(), pLen = p.length();

        if (sLen < pLen) {
            return new ArrayList<Integer>();
        }

        List<Integer> ans = new ArrayList<Integer>();
        int[] sCount = new int[26];
        int[] pCount = new int[26];
        for (int i = 0; i < pLen; ++i) {
            ++sCount[s.charAt(i) - 'a'];
            ++pCount[p.charAt(i) - 'a'];
        }

        // 第一个窗口判断:计数数组完全相等 = 字母异位词
        if (Arrays.equals(sCount, pCount)) {
            ans.add(0);
        }

        //窗口滑动,看下面的图即可理解
        for (int i = 0; i < sLen - pLen; ++i) {
            // 窗口左边界移出:左边字符计数-1
            --sCount[s.charAt(i) - 'a'];
            // 窗口右侧新增:新进来的字符计数+1
            ++sCount[s.charAt(i + pLen) - 'a'];

            //字母种类及其各自数量相等即为异位词
            if (Arrays.equals(sCount, pCount)) {
                ans.add(i + 1);
            }
        }

        return ans;
    }
}

这里并没有传统的指针来表示窗口,而是用简单的字母数量来维护窗口


难点再讲

java 复制代码
        // sCount:滑动窗口内字母计数,26个小写字母
        int[] sCount = new int[26];
        // pCount:p字符串固定的字母计数,相当于对比模板
        int[] pCount = new int[26];

这两个数组,就是用来存「每个字母出现了多少次」的统计表,因为只有小写 a-z,刚好 26 个,所以开长度 26 的数组

下标映射规则

字符 - 'a'(ASCII码从a开始)

  • 'a'-'a' → 0
  • 'b'-'a' → 1
  • ......
  • 'z'-'a' → 25

统计当前窗口里,s/p的子串各个字母有几个

java 复制代码
 ++sCount[s.charAt(i) - 'a'];
  1. s.charAt(i) 拿到字符串s下标i位置的字符,比如字符是 'b'
  2. s.charAt(i) - 'a'``'b' - 'a' = 1,得到数组下标 1
  3. sCount[1] 就是计数数组里,b 字母对应的计数器格子
  4. ++sCount[...]前置自增,等价于:这个格子里的数字 + 1

即sCount某字母 ++

窗口滑动图理解例子:

第一轮循环

第二轮循环

相关推荐
東隅已逝,桑榆非晚3 小时前
算法6. 双指针法-查找总价格为目标的两个商品
c++·学习·算法
Eyfcom3 小时前
〖物联网终端实战 01〗UWB 室内高精度定位:仓储 AGV 与人员的厘米级轨迹追踪
物联网·算法·物流系统·快递系统·跨境物流快递系统·物联网终端实战
bro_Java6664 小时前
《排序的底层逻辑:比较、交换与分治》
java·算法·排序算法
爱喝雪碧的可乐4 小时前
MATLAB
开发语言·算法·matlab
叼烟扛炮4 小时前
Linux 学习笔记(六十):单线程的逆袭——epoll 高并发服务器实战
linux·服务器·网络·笔记·学习·算法
careathers5 小时前
【数据结构】基于比较的排序算法 - 交换排序
数据结构·算法·排序算法
文丑颜不良啊5 小时前
LeetCode2081~2100题目解析
java·leetcode
Rabitebla6 小时前
【Linux操作系统】进程篇(十一):进程程序替换——从底层原理到 exec 函数族
linux·服务器·c++·笔记·学习·算法
tellmewhoisi6 小时前
深度学习0:数学知识:正态分布1
人工智能·深度学习·算法