JAVA练习277- 找到字符串中所有字母异位

题目概览

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

示例 1:

复制代码
输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。

示例 2:

复制代码
输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。

提示:

  • 1 <= s.length, p.length <= 3 * 104
  • s 和 p 仅包含小写字母

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

解题分析

方法:滑动窗口

仅包含小写字母可以用数组 mapping 来存储 p 每个字母出现的个数,然后定义双指针 i 和 j 都指向 s 第一个字母,再定义一个数组 repeatMapping 来存储 i 和 j 中间的所有的字母出现个数,每次遍历先判断当前 j 指向字母是否在 mapping 中出现,不出现则 i 和 j 都移动到当前位置往右一个位置,若出现则再判断在 repeatMapping 中出现个数是否小于 mapping,若小于,则 j 往右边移动,若大于等于,则往右移动 i 至当前指向字母相同字母的位置右边,并将移动过程所有字母出现个数再 repeatMapping 减去。每次移动判断一下 repeatMapping 是否已经和 mapping 相等,相等则记录索引,并往右移动一次 i,减去 repeatMapping 中 i 原来对应字母个数。

时间复杂度:O(n + m) (m 为 p 的长度)

空间复杂度:O(26)

java 复制代码
class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        char[] cs = s.toCharArray();
        int[] mapping = new int[26];
        for (char c: p.toCharArray()) {
            mapping[c - 'a']++;
        }
        int i = 0, j = 0;
        int[] repeatMapping = new int[26];
        int len = 0, pLen = p.length();
        List<Integer> result = new ArrayList<>();
        while(i < cs.length && j < cs.length) {
            if (mapping[cs[j] - 'a'] > 0) {
                if (repeatMapping[cs[j] - 'a'] >= mapping[cs[j] - 'a']) {
                    while(repeatMapping[cs[j] - 'a'] >= mapping[cs[j] - 'a']) {
                        repeatMapping[cs[i] - 'a']--;
                        ++i;
                        len--;
                    }
                    len++;
                    repeatMapping[cs[j] - 'a']++;
                } else {
                    repeatMapping[cs[j] - 'a']++;
                    len++;
                }
                j++;
            } else {
                j++;
                i = j;
                len = 0;
                repeatMapping = new int[26];
            }
            // System.out.println(String.format("len: %s, i: %d, j: %d", len, i, j));
            if (len == pLen) {
                result.add(i);
                len--;
                repeatMapping[cs[i] - 'a']--;
                i++;
            }
        }
        return result;
    }
}
相关推荐
而后笑面对14 分钟前
浅尝贝叶斯估计
人工智能·算法·机器学习
Elastic 中国社区官方博客22 分钟前
Observability:当 YAML 遇上 IConfiguration:OpenTelemetry .NET SDK 的声明式配置
大数据·开发语言·elasticsearch·搜索引擎·全文检索·.net
郑州光合科技余经理24 分钟前
同城商城源码:商品库和订单库怎么随包交付
android·java·开发语言·后端·uni-app·php·ai编程
\光辉岁月/25 分钟前
4.String类
java·面向对象·stringbuilder·string·stringbuffer·字符串类
welfare96237 分钟前
新号别搞:C++_list
开发语言·c++
数据狐(Datafox)39 分钟前
一文读懂京东商品详情 API:返回字段解读与 JSON 样例
开发语言·数据库·爬虫·json
蚰蜒螟1 小时前
从 Java SocketChannel 到 TCP 挥手:一次 close() 的完整调用链与引用计数解析
java·python·tcp/ip
坤坤子吖1 小时前
Linux 线程同步与互斥——条件变量与线程同步
linux·开发语言·c++·笔记·学习
damoluomu1 小时前
国产 Java CMS 的协议和坑,讲清楚
java·开发语言