10.Find All Anagrams in a String(在一个字符串中发现所有的目标串排列)
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;
}
}
最新文章
- 怎么在win7的64位旗舰版上配置coocs2d-x 3.2的android环境并且打包APK
- php一些特殊函数的使用实例详解
- WCF概念
- hrb 2134 素数
- linux之I2C裸机驱动解析(转)
- 51Nod 1201 整数划分 (经典dp)
- tomcat的OutOfMemoryError(PermGen space)解决方法
- 使用Clean() 去掉由函数自动生成的字符串中的双引号
- Spring in action (1)
- vue二次实战(一)
- 在IDEA中实战Git
- fetch使用的常见问题及其解决办法
- [LeetCode] 860. Lemonade Change_Easy tag: Greedy
- 陌上花开——CDQ分治
- Linux服务器开启ssh服务,实现ssh远程登陆!
- 深入理解ClassLoader工作机制(jdk1.8)
- iOS 如何写出更加严谨的应用
- Netty优雅退出机制和原理
- Delphi XE Starter Essentials 中文目录
- 【转】sql server日期比较
热门文章
- 2016.4.6 WinForm显示PDF两种方法
- leetcode633
- Delphi Cookie
- ffmpeg: ‘UINT64_C’ was not declared in this scope (转)
- DAY13-前端之jQuery
- linux进程的软中断通信
- 指定jdk编译或运行
- jQuery实现按钮5秒后可以点击
- 算法Sedgewick第四版-第1章基础-1.3Bags, Queues, and Stacks-001可变在小的
- Effective Objective-C [下]