题目描述
- 因为自己写的复杂度已经到了 O(n),就没有再参考题解的优化了
- 更新:滑动窗口方法
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/a254d594ceafddfdd48758a076c59ee7.png)
思路 & 代码
- 用一个 int[ ] count 来存储当前判断子串的各字母出现次数
- getCount():对当前子串,求 count,时间复杂度 O(n)
- formatString():用 count 转换成当前子串的对比格式,时间复杂度 O(1)
- 对比格式:如"abcccz" 变成 “a1b1c3z1”
- 实际上,getCount只要使用两次即可:一次给 p,一次给 s 的第一个子串
- 往后,s 的字串只需要对之前的 count 进行微小更新即可
class Solution {
public List<Integer> findAnagrams(String s, String p) {
List<Integer> ans = new ArrayList<>();
int pLen = p.length();
if(s.length() < pLen){
return ans;
}
char[] sC = s.toCharArray();
char[] pC = p.toCharArray();
int[] count = new int[26];
getCount(pC, count);
String formatP = formatString(count);
count = new int[26];
getCount(s.substring(0, pLen).toCharArray(), count);
String formatQ = formatString(count);
if(formatQ.equals(formatP)){
ans.add(0);
}
for(int i = 1; i + pLen <= s.length(); i++){
char last = sC[i + pLen - 1];
char pre = sC[i - 1];
if(last != pre){
count[last - 'a']++;
count[pre - 'a']--;
formatQ = formatString(count);
}
if(formatQ.equals(formatP)){
ans.add(i);
}
}
return ans;
}
void getCount(char[] now, int[] count){
for(char ch : now){
count[ch - 'a']++;
}
}
String formatString(int[] count){
StringBuilder formatNow = new StringBuilder();
for(int i = 0; i < 26; i++){
if(count[i] != 0){
formatNow.append((char)(i + 'a'));
formatNow.append(count[i]);
}
}
return formatNow.toString();
}
}
更新版
- 现在看之前的代码简直不堪入目…好长好冗余
- 新思路:等大滑动窗口,数组维护滑动窗口值,Arrays.equals() 用作对比
class Solution {
public List<Integer> findAnagrams(String s, String p) {
if(s.length() < p.length()) {
return new ArrayList<>();
}
int[] sCounts = new int[26];
int[] pCounts = new int[26];
List<Integer> ans = new ArrayList<>();
for(int i = 0; i < p.length(); i++) {
sCounts[s.charAt(i) - 'a']++;
pCounts[p.charAt(i) - 'a']++;
}
if(Arrays.equals(sCounts, pCounts)) {
ans.add(0);
}
int left = 0, right = p.length() - 1;
while(right < s.length() - 1) {
sCounts[s.charAt(left++) - 'a']--;
sCounts[s.charAt(++right) - 'a']++;
if(Arrays.equals(sCounts, pCounts)) {
ans.add(left);
}
}
return ans;
}
}
三刷 - 每日一题
class Solution {
public List<Integer> findAnagrams(String s, String p) {
if(s.length() < p.length()) return new ArrayList<>();
List<Integer> ans = new ArrayList<>();
int[] sCounts = new int[26];
int[] pCounts = new int[26];
for(int i = 0; i < p.length(); i++) {
sCounts[s.charAt(i) - 'a']++;
pCounts[p.charAt(i) - 'a']++;
}
if(Arrays.equals(sCounts, pCounts)) ans.add(0);
int left = 0, right = p.length() - 1;
while(right < s.length() - 1) {
sCounts[s.charAt(left++) - 'a']--;
sCounts[s.charAt(++right) - 'a']++;
if(Arrays.equals(sCounts, pCounts)) ans.add(left);
}
return ans;
}
}