Level:

  Easy

题目描述:

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 sand 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".

思路分析:

  知识点:滑动窗口

  关键点一:像这种找子串的可以使用滑动窗口Sliding Window来做。这个窗口由left和right来约束[left,right]这个闭区间,刚开始知识left=right=0,然后left不变,right不断增长,直到到达某个值,left和right一起增长,这样就实现了窗口的创建和向下滑动。

  关键点二:对于p中出现的字符以及次数需要记下来。可以使用一个数组ascaiiNums,长度为256,是因为ascaii一共只有256个,初始化的值表示角标对应的ascaii字符在p中出现的次数,那么没有出现过的就是0.之后如果s中出现过该字符,那么数组对应位置的值就减一。如果减之后的值大于等于0,就说明p中该字符出现了一次,这时p中未出现的字符数量count就减一。之所以要判断是>=0,是因为如果数组中原来的值是0(说明p中没有出现),那么减一后就成了负的,这种情况下p中剩下未出现的字符的count数值保持不变。如果count的值为0,说明p中的字符全出现了,找到一个符合条件的子串,left就是子串的首地址。之后要向右滑动窗口,移动的方法是left++,right++,更新p中未出现的字符个数count。

代码:

public class Solution{
public List<Integer>findAnagrams(String s,String p){
ArrayList<Integer>res=new ArrayList<>();
if(s==null||p==null||p.length()>s.length())
return res;
int []map=new int [256]; //记录p中出现的元素
for(char c:p.toCharArray())
map[c]++; //以c的Ascall为下标的值加一,其余没出现的都为0;
int count=p.length(); //记录p中还未出现的字符个数
int left=0; //窗口左指针
int right=0; //窗口右指针
while(right<s.length()){
char ch=s.charAt(right);
map[ch]--;
if(map[ch]>=0) //证明ch是p中的字符
count--; //p中未出现的个数减一
if(right-left+1==p.length()){
if(count==0) //说明p中的字符都已经出现
res.add(left);
char ch1=s.charAt(left);
map[ch1]++;
if(map[ch1]>0)//证明当前窗口最左边的值在p中存在,那么由于窗口要向下滑动一位,会舍弃该值,则count的数目就应该加1
count++;
left++;//窗口向下滑动
right++;
}else{
right++;
}
}
return res;
}
}

最新文章

  1. 怎么在win7的64位旗舰版上配置coocs2d-x 3.2的android环境并且打包APK
  2. php一些特殊函数的使用实例详解
  3. WCF概念
  4. hrb 2134 素数
  5. linux之I2C裸机驱动解析(转)
  6. 51Nod 1201 整数划分 (经典dp)
  7. tomcat的OutOfMemoryError(PermGen space)解决方法
  8. 使用Clean() 去掉由函数自动生成的字符串中的双引号
  9. Spring in action (1)
  10. vue二次实战(一)
  11. 在IDEA中实战Git
  12. fetch使用的常见问题及其解决办法
  13. [LeetCode] 860. Lemonade Change_Easy tag: Greedy
  14. 陌上花开——CDQ分治
  15. Linux服务器开启ssh服务,实现ssh远程登陆!
  16. 深入理解ClassLoader工作机制(jdk1.8)
  17. iOS 如何写出更加严谨的应用
  18. Netty优雅退出机制和原理
  19. Delphi XE Starter Essentials 中文目录
  20. 【转】sql server日期比较

热门文章

  1. 2016.4.6 WinForm显示PDF两种方法
  2. leetcode633
  3. Delphi Cookie
  4. ffmpeg: ‘UINT64_C’ was not declared in this scope (转)
  5. DAY13-前端之jQuery
  6. linux进程的软中断通信
  7. 指定jdk编译或运行
  8. jQuery实现按钮5秒后可以点击
  9. 算法Sedgewick第四版-第1章基础-1.3Bags, Queues, and Stacks-001可变在小的
  10. Effective Objective-C [下]