438. Find All Anagrams in a String

Given a string s and a non-empty string p, find all the start indices of p's anagrams in s.

Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.

The order of output does not matter.

Example 1:

Input:
s: "cbaebabacd" p: "abc"

Output:
[0, 6]

Explanation:
The substring with start index = 0 is "cba", which is an anagram of "abc".
The substring with start index = 6 is "bac", which is an anagram of "abc".

Example 2:

Input:
s: "abab" p: "ab"

Output:
[0, 1, 2]

Explanation:
The substring with start index = 0 is "ab", which is an anagram of "ab".
The substring with start index = 1 is "ba", which is an anagram of "ab".
The substring with start index = 2 is "ab", which is an anagram of "ab".

滑动窗口,每次添加右边的一个字符,删除左边的一个字符,看看是不是满足各种字符数都大于等于p中各种字符的字符数的条件

注意检测的时候完全没必要扫描窗口里的所有字符来统计个数,窗口滑动时只需要考虑一个添加进来的字符和一个删除的字符,因为只有这两个字符出现了变动,用needed标记“缺失”的字符数,假设字符为X,串P中字符X的个数为P(X),当X等于P(X)且X需要删除的时候才会使得“缺失”的字符数+1 ;当X等于P(X)-1且需要添加的时候才会使得“缺失”的字符数-1


public class Solution {
    public List<Integer> findAnagrams(String s, String p)
	{
		List<Integer> retlist=new ArrayList<>();
		int slen=s.length();
		int plen=p.length();
		if(slen<plen)
			return retlist;
		int[] carr=new int[128];
		for(int i=0;i<plen;i++)
			carr[p.charAt(i)]++;
		
		int need=0;
		int[] count=new int[128];
		
		for(int i=0;i<plen;i++)
			count[s.charAt(i)]++;
		
		for(char c='a';c<='z';c++)
			if(count[c]<carr[c])
				need++;
		
		if(need==0)
			retlist.add(0);
		
		for(int i=plen;i<slen;i++)
		{
			char preChar=s.charAt(i-plen);
			char nowChar=s.charAt(i);
			if(--count[preChar]==carr[preChar]-1)
				need++;
			if(++count[nowChar]==carr[nowChar])
				need--;
			if(need==0)
				retlist.add(i-plen+1);
		}
		
		return retlist;
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值