标签:长度 bsp pre 计数 == lis close closed ret
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 40,000.
The order of output does not matter.
Example
Given s = "cbaebabacd"
p = "abc"
return [0, 6]
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".
思路:
基础思路:
1,找到所有的subarray。
2,看每一个是不是Anagram。只要看两个字符串里面字符出现的次数是不是一样就可以区别是不是anagram
优化:
可以当作滑动窗口来做,窗口向后移动的过程中,只要只要移动的前一位(要抛弃的那一位)以及后面移动的那一位(要添加的那一位)是不是一样,就可以判断了。
如果是一样的,那就可以把新的窗口字符串添加到答案里面。
如果不是一样的,就要把窗口后移并且从新前面的所有过程。
code里面的while loop中三个if:
if(sum[s.charAt(start) - ‘a‘] >= 1){} :找到了一个点包含了P的某个char 也就是条件1: 包含p中的字符
if(matched == lenP){} : match了P长度的字符串 也就是条件2: 包含所有p中的字符
if(end - start == lenP){} :窗口滑动过程 也就是条件3:保证包含所有的字符,并且没有多余的字符,也就是长度限制条件
public class Solution { /** * @param s a string * @param p a non-empty string * @return a list of index */ public List<Integer> findAnagrams(String s, String p) { //find all subarray //sort subarray and P // see if it match List<Integer> ans = new ArrayList <Integer>(); int[] sum = new int[30]; int plength = p.length(); int slength = s.length(); for(char c : p.toCharArray()){ // 统计不同字母出现的个数 sum[c - ‘a‘] ++; } int start = 0, end = 0, matched = 0; while(end < slength){ if(sum[s.charAt(end) - ‘a‘] >= 1){ // 至少有一个跟p相同的字母 matched ++; // match的个数增加一个 } sum[s.charAt(end) - ‘a‘] --; // 删掉已经match过的那个数字 end ++; if(matched == plength) { ans.add(start); } if(end - start == plength){ // 窗口滑动时,要抛弃前面那个数 if(sum[s.charAt(start) - ‘a‘] >= 0){ //所以需要 match-1 matched --; } sum[s.charAt(start) - ‘a‘] ++;//因为把前一位扔掉了 //所以前一位出现的计数要还原一个 start ++; // start向前移动一位 } } return ans; } }
标签:长度 bsp pre 计数 == lis close closed ret
原文地址:http://www.cnblogs.com/tritritri/p/7398696.html