Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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)

AltStyle によって変換されたページ (->オリジナル) /