Skip to content

Commit a2f3e2e

Browse files
author
weiy
committed
find all angrams in a string easy
1 parent 49a4389 commit a2f3e2e

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

DP/FindAllAnagramsInAString.py

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
"""
2+
Given a string s and a non-empty string p, find all the start indices of p's anagrams in s.
3+
4+
Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.
5+
6+
The order of output does not matter.
7+
8+
Example 1:
9+
10+
Input:
11+
s: "cbaebabacd" p: "abc"
12+
13+
Output:
14+
[0, 6]
15+
16+
Explanation:
17+
The substring with start index = 0 is "cba", which is an anagram of "abc".
18+
The substring with start index = 6 is "bac", which is an anagram of "abc".
19+
Example 2:
20+
21+
Input:
22+
s: "abab" p: "ab"
23+
24+
Output:
25+
[0, 1, 2]
26+
27+
Explanation:
28+
The substring with start index = 0 is "ab", which is an anagram of "ab".
29+
The substring with start index = 1 is "ba", which is an anagram of "ab".
30+
The substring with start index = 2 is "ab", which is an anagram of "ab".
31+
32+
33+
给定一个字符串 s 和 非空字符串 p。 找到所有 p 在 s 中的变位词,将变位词开始部分的索引添加到结果中。
34+
35+
字符串包含的字符均为小写英文字母。
36+
37+
结果的顺序无关紧要。
38+
39+
40+
思路:
41+
看到标的是个 easy .. 估计数据不会很大,直接 sorted(s[i:i+len(p)]) == sorted(p) 判断了..
42+
结果是 TLE。
43+
44+
好吧,只能认真思考下了。
45+
46+
想到的是利用动态规划,还有点回溯的味道。
47+
48+
子问题为:
49+
当前点加上之前的点是否覆盖了全部的p。
50+
51+
若全部覆盖了,则返回 i - len(p) + 1 的开始索引,同时,将 s[i - len(p) + 1] 处的字符添加到 dp 的判断点中。
52+
这样做可以扫描到这种情况:
53+
s = ababab
54+
p = ab
55+
循环这种。
56+
57+
若没有存在于最后一个dp中,那么先判断是否有重复:
58+
1. 如果在 p 中,但不在上一个子问题的需求解里。
59+
2. 如果与最前面的一个字符发生了重复。
60+
3. 如果与之前的一个字符不同。
61+
满足这三个条件那么可以无视这个重复的字符。
62+
比如这样:
63+
s = abac
64+
p = abc
65+
66+
这样相当于把重复的一个 a 忽略掉了。
67+
同时还要判断是否它的前一个是否一致,一致的话就不能单纯的忽略了。
68+
69+
s = abaac / aabc
70+
p = abc
71+
72+
没有满足的上述三个条件,那么重新复制一份原始子问题,然后将当前字符判断一下,继续下一个循环即可。
73+
74+
beat 99% 84ms
75+
测试地址:
76+
https://leetcode.com/problems/find-all-anagrams-in-a-string/description/
77+
78+
"""
79+
class Solution(object):
80+
def findAnagrams(self, s, p):
81+
"""
82+
:type s: str
83+
:type p: str
84+
:rtype: List[int]
85+
"""
86+
87+
# p = sorted(p)
88+
if not s:
89+
return []
90+
_p = {}
91+
92+
for i in p:
93+
try:
94+
_p[i] += 1
95+
except:
96+
_p[i] = 1
97+
98+
result = []
99+
100+
x = _p.copy()
101+
if s[0] in _p:
102+
x[s[0]] -= 1
103+
if not x[s[0]]:
104+
x.pop(s[0])
105+
106+
dp = x
107+
if not dp:
108+
return [i for i in range(len(s)) if s[i] == p]
109+
110+
for i in range(1, len(s)):
111+
if s[i] in dp:
112+
t = dp
113+
t[s[i]] -= 1
114+
if not t[s[i]]:
115+
t.pop(s[i])
116+
117+
if not t:
118+
result.append(i-len(p)+1)
119+
x = {}
120+
_t = s[i-len(p)+1]
121+
x[_t] = 1
122+
123+
dp = x
124+
else:
125+
if s[i] in _p and s[i] != s[i-1] and s[i] == s[i-len(p)+1]:
126+
continue
127+
x = _p.copy()
128+
if s[i] in x:
129+
x[s[i]] -= 1
130+
if not x[s[i]]:
131+
x.pop(s[i])
132+
dp = x
133+
134+
return result
135+

0 commit comments

Comments
 (0)