您的位置:首页 > 其它

leetcode[Find All Anagrams in a String]

2017-07-21 15:00 423 查看
错误解法(这种解法对于很大的输入会造成超时,循环是O(N),判断的函数又是O(N),总复杂度是O(N^2)了):

public class Solution {
private boolean isSame(char[] a, char[] b){
for(int i = 0; i < a.length; i++){
if(a[i] != b[i])
return false;
}
return true;
}

public List<Integer> findAnagrams(String s, String p) {
List<Integer> res = new ArrayList<>();
char[] pa = p.toCharArray();
Arrays.sort(pa);
for(int i = 0; i < s.length() - p.length() + 1; i++){
char[] sa = s.substring(i, i + p.length()).toCharArray();
Arrays.sort(sa);
if(isSame(sa, pa)){
res.add(i);
}
}

return res;
}
}

正解:

public class Solution {
//Same idea from a fantastic sliding window template,与比较子串有关的都可以采用这种算法,window就是子串
//Time Complexity will be O(n) because the "start" and "end" points will only move from left to right once.
public List<Integer> findAnagrams(String s, String p) {
List<Integer> list = new ArrayList<>();
if (s == null || s.length() == 0 || p == null || p.length() == 0)
return list;

int[] hash = new int[256]; //character hash,256保险起见,字符个数不可能多于256个

//record each character in p to hash
for (char c : p.toCharArray()) {
hash[c]++;
}
//two points, initialize count to p's length
int left = 0, right = 0, count = p.length();
while (right < s.length()) {
//move right everytime, if the character exists in p's hash, decrease the count
//current hash value >= 1 means the character is existing in p
if (hash[s.charAt(right)] >= 1) {
count--;
}
hash[s.charAt(right)]--;
right++;

//when the count is down to 0, means we found the right anagram
//then add window's left to result list
if (count == 0) {
list.add(left);
}
//if we find the window's size equals to p, then we have to move left (narrow the window) to find the new match window
//++ to reset the hash because we kicked out the left
//only increase the count if the character is in p
//the count >= 0 indicate it was original in the hash, cuz it won't go below 0
if (right - left == p.length() ) {//需要找一个新的window了,需要移动left,而且要将count与hash复原
if (hash[s.charAt(left)] >= 0) {//因为left只移动一个位置,而中间right移动那些不用变(之后也会同样地),所以复原一个count++
count++;
}
hash[s.charAt(left)]++;//因为left只移动一个位置,而中间right移动那些不用变(之后也会同样地),所以复原一个hash[s.charAt(left)]
left++;
}
}
return list;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: