Skip to content

Commit 65ada08

Browse files
committed
438_Find_All_Anagrams_in_a_String
1 parent 9e91a61 commit 65ada08

File tree

3 files changed

+122
-0
lines changed

3 files changed

+122
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ Remember solutions are only solutions to given problems. If you want full study
130130
| 421 | [Maximum XOR of Two Numbers in an Array](https://leetcode.com/problems/maximum-xor-of-two-numbers-in-an-array/) | [Python](https://github.com/qiyuangong/leetcode/blob/master/python/421_Maximum_XOR_of_Two_Numbers_in_an_Array.py) | Check 0~32 prefix, check if there is x y in prefixes, where x ^ y = answer ^ 1, O(32n) and O(n) |
131131
| 422 | [Valid Word Square](https://leetcode.com/problems/valid-word-square/) ♥ | [Python](https://github.com/qiyuangong/leetcode/blob/master/python/422_Valid_Word_Square.py) | Compare row with column, O(n^2) |
132132
| 434 | [Number of Segments in a String](https://leetcode.com/problems/number-of-segments-in-a-string/description/) | [Python](https://github.com/qiyuangong/leetcode/blob/master/python/434_Number_of_Segments_in_a_String.py) [Java](https://github.com/qiyuangong/leetcode/blob/master/java/434_Number_of_Segments_in_a_String.java) | 1. trim &split<br>2. Find segment in place |
133+
| 438 | [Find All Anagrams in a String](https://leetcode.com/problems/number-of-segments-in-a-string/description/) | [Python](https://github.com/qiyuangong/leetcode/blob/master/python/438_Find_All_Anagrams_in_a_String.py) [Java](https://github.com/qiyuangong/leetcode/blob/master/java/438_Find_All_Anagrams_in_a_String.java) | Build a char count list with 26-256 length. Note that this list can be update when going through the string. O(n) and O(1) |
133134
| 443 | [String Compression](https://leetcode.com/problems/string-compression/description/) | [Python](https://github.com/qiyuangong/leetcode/blob/master/python/443_String_Compression.py) [Java](https://github.com/qiyuangong/leetcode/blob/master/java/443_String_Compression.java) | Maintain curr, read, write and anchor (start of this char). |
134135
| 453 | [Number of Segments in a String](https://leetcode.com/problems/minimum-moves-to-equal-array-elements/description/) | [Python](https://github.com/qiyuangong/leetcode/blob/master/python/453_Minimum_Moves_to_Equal_Array_Elements.py) [Java](https://github.com/qiyuangong/leetcode/blob/master/java/453_Minimum_Moves_to_Equal_Array_Elements.java) | Each move is equal to minus one element in array, so the answer is the sum of all elements after minus min. |
135136
| 463 | [Island Perimeter](https://leetcode.com/problems/island-perimeter/) | [Python](https://github.com/qiyuangong/leetcode/blob/master/python/463_Island_Perimeter.py) [Java](https://github.com/qiyuangong/leetcode/blob/master/java/463_Island_Perimeter.java) | math, find the area, actual number, then find the digit |
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
class Solution {
2+
public List<Integer> findAnagrams(String s, String p) {
3+
// https://leetcode.com/problems/find-all-anagrams-in-a-string/discuss/92015/ShortestConcise-JAVA-O(n)-Sliding-Window-Solution
4+
List<Integer> list = new ArrayList<>();
5+
if (s == null || s.length() == 0 || p == null || p.length() == 0) return list;
6+
int[] hash = new int[256]; //character hash
7+
//record each character in p to hash
8+
for (char c : p.toCharArray()) {
9+
hash[c]++;
10+
}
11+
//two points, initialize count to p's length
12+
int left = 0, right = 0, count = p.length();
13+
while (right < s.length()) {
14+
//move right everytime, if the character exists in p's hash, decrease the count
15+
//current hash value >= 1 means the character is existing in p
16+
if (hash[s.charAt(right++)]-- >= 1) count--;
17+
//when the count is down to 0, means we found the right anagram
18+
//then add window's left to result list
19+
if (count == 0) list.add(left);
20+
//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
21+
//++ to reset the hash because we kicked out the left
22+
//only increase the count if the character is in p
23+
//the count >= 0 indicate it was original in the hash, cuz it won't go below 0
24+
if (right - left == p.length() && hash[s.charAt(left++)]++ >= 0) count++;
25+
}
26+
return list;
27+
}
28+
/*public List<Integer> findAnagrams(String s, String p) {
29+
List<Integer> list = new ArrayList<Integer>();
30+
int ls = s.length(), lp = p.length();
31+
for (int i = 0; i <= ls - lp; i++) {
32+
boolean flag = true;
33+
String sub = s.substring(i, i + lp);
34+
int[] charCnt = new int[256];
35+
for (int j = 0; j < sub.length(); j++) {
36+
charCnt[sub.charAt(j)]++;
37+
}
38+
for (int j = 0; j < lp; j++) {
39+
charCnt[p.charAt(j)]--;
40+
}
41+
for (int j = 0; j < charCnt.length; j++) {
42+
if (charCnt[j] != 0) {
43+
flag = false;
44+
break;
45+
}
46+
}
47+
if (flag) {
48+
list.add(i);
49+
}
50+
}
51+
return list;
52+
}*/
53+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
class Solution(object):
2+
def findAnagrams(self, s, p):
3+
"""
4+
:type s: str
5+
:type p: str
6+
:rtype: List[int]
7+
"""
8+
res = []
9+
if s is None or p is None or len(s) == 0 or len(p) == 0:
10+
return res
11+
char_map = [0] * 256
12+
for c in p:
13+
char_map[ord(c)] += 1
14+
left, right, count = 0, 0, len(p)
15+
while right < len(s):
16+
if char_map[ord(s[right])] >= 1:
17+
count -= 1
18+
char_map[ord(s[right])] -= 1
19+
right += 1
20+
if count == 0:
21+
res.append(left)
22+
if right - left == len(p):
23+
if char_map[ord(s[left])] >= 0:
24+
count += 1
25+
char_map[ord(s[left])] += 1
26+
left += 1
27+
return res
28+
29+
# def findAnagrams(self, s, p):
30+
# if len(s) < len(p):
31+
# return []
32+
# res = []
33+
# p_len = len(p)
34+
# bit_map = []
35+
# for _ in range(26):
36+
# bit_map.append(0)
37+
# for c in p:
38+
# bit_map[ord(c) - ord('a')] += 1
39+
# s_p = str(bit_map)
40+
# for i in range(26):
41+
# bit_map[i] = 0
42+
# for i in range(p_len - 1):
43+
# bit_map[ord(s[i]) - ord('a')] += 1
44+
# for i in range(p_len - 1, len(s)):
45+
# bit_map[ord(s[i]) - ord('a')] += 1
46+
# if i - p_len >= 0:
47+
# bit_map[ord(s[i - p_len]) - ord('a')] -= 1
48+
# if str(bit_map) == s_p:
49+
# res.append(i - p_len + 1)
50+
# return res
51+
52+
# def findAnagrams(self, s, p):
53+
# """
54+
# :type s: str
55+
# :type p: str
56+
# :rtype: List[int]
57+
# """
58+
# res = []
59+
# pCounter = collections.Counter(p)
60+
# sCounter = collections.Counter(s[:len(p)-1])
61+
# for i in range(len(p)-1,len(s)):
62+
# sCounter[s[i]] += 1 # include a new char in the char_map
63+
# if sCounter == pCounter: # This step is O(1), since there are at most 26 English letters
64+
# res.append(i-len(p)+1) # append the starting index
65+
# sCounter[s[i-len(p)+1]] -= 1 # decrease the count of oldest char in the window
66+
# if sCounter[s[i-len(p)+1]] == 0:
67+
# del sCounter[s[i-len(p)+1]] # remove the count if it is 0
68+
# return res

0 commit comments

Comments
 (0)