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

链接:https://leetcode.com/problems/find-all-anagrams-in-a-string/#/description

3/25/2017

抄答案

注意的错误:

1. 如果用set和hashmap注意window长度内可能有重复的字符

2. pattern里会出现重复的字符

因为这两个错误,尤其是第二个,我的答案都错了,也想不出其他方法。

别人的

解决的问题:

1. count什么情况-:字符是需要的时候(本身在pattern里,而且还不到我们需要的数目)。count什么情况+:最左边被left过滤掉的字符是我们需要的,也是下面right向右需要找的。

2. hash当中的值就是我们还缺的

3. 我们的window除了开始一直是定长,window当中很有可能有不需要的元素,需不需要担心?不需要,在这种情况下因为第一个判断条件不满足,count不会为0,不为0也就不会被加到结果中去。

4. 现在看着答案可以跟着思路理出来。但是如何将来还会想到呢?简单题吗?我觉得不是。

 1 public class Solution {
 2 public List<Integer> findAnagrams(String s, String p) {
 3     List<Integer> list = new ArrayList<>();
 4     if (s == null || s.length() == 0 || p == null || p.length() == 0) return list;
 5     int[] hash = new int[256]; //character hash
 6     //record each character in p to hash
 7     for (char c : p.toCharArray()) {
 8         hash[c]++;
 9     }
10     //two points, initialize count to p's length
11     int left = 0, right = 0, count = p.length();
12     while (right < s.length()) {
13         //move right everytime, if the character exists in p's hash, decrease the count
14         //current hash value >= 1 means the character is existing in p
15         if (hash[s.charAt(right)] >= 1) count--;
16         hash[s.charAt(right)]--;
17         right++;
18         
19         //when the count is down to 0, means we found the right anagram
20         //then add window's left to result list
21         if (count == 0) list.add(left);
22     
23         //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
24         //++ to reset the hash because we kicked out the left
25         //only increase the count if the character is in p
26         //the count >= 0 indicate it was original in the hash, cuz it won't go below 0
27         if (right - left == p.length()) {
28             if (hash[s.charAt(left)] >= 0) count++;
29             hash[s.charAt(left)]++;
30             left++;
31         }
32     }
33     return list;
34 }
35 }

别人的相关总结:

https://discuss.leetcode.com/topic/68976/sliding-window-algorithm-template-to-solve-all-the-leetcode-substring-search-problem

更多讨论(好像没有发现其他思路)

https://discuss.leetcode.com/category/563/find-all-anagrams-in-a-string

原文地址:https://www.cnblogs.com/panini/p/6619635.html