LeetCode #438 找到字符串中所有字母异位词
Posted 三笠·阿卡曼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode #438 找到字符串中所有字母异位词相关的知识,希望对你有一定的参考价值。
题目给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。
字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。
说明:
字母异位词指字母相同,但排列不同的字符串。
不考虑答案输出的顺序
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-all-anagrams-in-a-string
示例
最佳代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author vleus
* @date 2021年05月13日 22:51
*/
public class FindALLAnagrams {
//方法一: 枚举所有长度为p.length()的子串
public List<Integer> findAnagrams1(String s, String p) {
//定义一个结果列表
ArrayList<Integer> result = new ArrayList<>();
//1、统计p中所有字符出现的频次
int[] pCharCounts = new int[26];
for (int i = 0; i < p.length(); i++) {
pCharCounts[p.charAt(i) - 'a']++;
}
//2、遍历s,以每一个字符作为起始,考察长度为p.length()的子串
for (int i = 0; i <= s.length() - p.length(); i++) {
//3、判断当前子串是否为p的字母异位词
boolean isMatched = true;
int[] subStrCharCounts = new int[26];
for (int j = i; j < i + p.length(); j++) {
subStrCharCounts[s.charAt(j) - 'a']++;
//判断当前字符频次如果超过了p中的频次,就一定不符合要求
if(subStrCharCounts[s.charAt(j) - 'a'] > pCharCounts[s.charAt(j) - 'a']){
isMatched = false;
break;
}
}
if (isMatched) {
result.add(i);
}
}
return result;
}
//方法二:滑动窗口法,分别移动起始和结束位置
public List<Integer> findAnagrams(String s, String p) {
//定义一个结果列表
ArrayList<Integer> result = new ArrayList<>();
//1、统计p中所有字符出现的频次
int[] pCharCounts = new int[26];
for (int i = 0; i < p.length(); i++) {
pCharCounts[p.charAt(i) - 'a']++;
}
//统计子串中所有字符出现频次的数组
int[] subStrCharCounts = new int[26];
//定义起始和结束位置
int start = 0,end = 1;
//2.移动指针,总是截取字符串出现频次全部小于等于p中字符频次的子串
while (end <= s.length()) {
char newChar = s.charAt(end - 1);
subStrCharCounts[newChar - 'a']++;
//3.判断当前子串是否符合要求
//如果新增字符导致子串频次超出了p中频次,那么移动start,消除新增的字符的影响
while (subStrCharCounts[newChar - 'a'] > pCharCounts[newChar - 'a'] && start < end) {
char removedChar = s.charAt(start);
subStrCharCounts[removedChar - 'a']--;
start++;
}
//如果当前子串等于p的长度,那么就是一个字母异位词
if (end - start == p.length()) {
result.add(start);
}
end++;
}
return result;
}
public static void main(String[] args) {
String s = "cbaebabacd";
String p = "abc";
FindALLAnagrams findALLAnagrams = new FindALLAnagrams();
System.out.println(Arrays.toString(findALLAnagrams.findAnagrams(s,p).toArray()));
}
}
以上是关于LeetCode #438 找到字符串中所有字母异位词的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 438 找到字符串中所有字母异位词[数组 滑动窗口] HERODING的LeetCode之路
leetcode 438. 找到字符串中所有字母异位词(Find All Anagrams in a String)
LeetCode 438. 找到字符串中所有字母异位词 / 786. 第 K 个最小的素数分数 / 400. 第 N 位数字(优先队列,二分+双指针)