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

一、题目描述

给定两个字符串 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 仅包含小写字母

二、解决思路

1、直观解法,for循环遍历原数组,每次截取p长度,判断是否是异位词

复制代码
class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        List<Integer> list = new LinkedList<>();
        if(s == null || p == null || s.length() == 0 || p.length() == 0){
            return list;
        }
        if(p.length() > s.length()){
            return list;
        }
        int count = p.length();
        String cur;
        char[] curChars;
        Set<String> set = new HashSet<>();
        //需转换为数组进行排序
        set.add(sortString(p));
        for(int i = 0;i < s.length() && i < s.length() - count + 1;i++){
            //截取不包含i+count位置的元素
            cur = s.substring(i,i + count);
            if(set.contains(sortString(cur))){
                list.add(i);
            }
        }
        return list;
    }
    //对一个字符串内部按字母排序,返回新字符串
    public String sortString(String str){
        char[] dest = str.toCharArray();
        Arrays.sort(dest);
        return String.valueOf(dest);
    }
}

2、滑动窗口

定长滑窗。枚举 s 的所有长为 n 的子串 s

,如果 s

的每种字母的出现次数,和 p 的每种字母的出现次数都相同,那么 s

是 p 的异位词。

复制代码
class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        List<Integer> ans = new ArrayList<>();
        int[] cntP = new int[26]; // 统计 p 的每种字母的出现次数
        int[] cntS = new int[26]; // 统计 s 的长为 p.length() 的子串 s' 的每种字母的出现次数
        for (char c : p.toCharArray()) {
            cntP[c - 'a']++; // 统计 p 的字母
        }
        for (int right = 0; right < s.length(); right++) {
            cntS[s.charAt(right) - 'a']++; // 右端点字母进入窗口
            int left = right - p.length() + 1;
            if (left < 0) { // 窗口长度不足 p.length()
                continue;
            }
            if (Arrays.equals(cntS, cntP)) { // s' 和 p 的每种字母的出现次数都相同
                ans.add(left); // s' 左端点下标加入答案
            }
            cntS[s.charAt(left) - 'a']--; // 左端点字母离开窗口
        }
        return ans;
    }
}
相关推荐
好易学·数据结构5 分钟前
可视化图解算法52:数据流中的中位数
数据结构·算法·leetcode·面试·力扣·笔试·牛客
面朝大海,春不暖,花不开6 分钟前
Java服务提供者模式实现指南
java·开发语言·python
有你有我OK9 分钟前
java 验证ip是否可达
java·开发语言·tcp/ip
不知疲倦的仄仄12 分钟前
RabbitMQ多角度可靠性分析/基于Java代码深度解析
java·spring·rabbitmq·java-rabbitmq
dying_man30 分钟前
LeetCode--35.搜索插入位置
算法·leetcode
真实的菜2 小时前
适配器模式:接口转换的神奇魔法[特殊字符],让不兼容的类和谐共处!
java·适配器模式
骚戴2 小时前
SpringBoot源码解析(十五):spring-boot-autoconfigure.jar的模块化设计
java
YuTaoShao2 小时前
Java八股文——计算机网络「应用层篇」
java·网络·计算机网络
Mryan20053 小时前
Android 应用多语言与系统语言偏好设置指南
android·java·国际化·android-studio·多语言
鲁Q同志4 小时前
若依导出模板时设置动态excel下拉框(表连接的)
java·excel