【LeetCode 热题 100】438. 找到字符串中所有字母异位词 | python 【中等】
继续学!嗨起来!!!(正确率已经下30%了,我在干什么)
题目:
438. 找到字符串中所有字母异位词
给定两个字符串 s
和 p
,找到 s
中所有 p
的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
示例 1:
输入: s = "cbaebabacd", p = "abc" 输出: [0,6] 解释: 起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。 起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
注意:
- 是异位词
- 要求时间短
- 滑动窗口解法(类似双指针)
不熟悉的操作:
[0]*26 = np.zeros([1,26])
ord()
是 Python 的内置函数,用于获取字符的 ASCII 码值
标准解法:
1.将p的字母和数量储存起来,滑动窗口
不用每次排序
不是用字典储存,而是一个列表,从a到z存字母个数【天才想法!】
一些思考:如果用字典呢?不过字典还要搜索,但如果不在就可以跳过(跟为负跳过是一样的捏)
里面的数据不用遍历:移过则出,没过则进
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
s_len, p_len = len(s), len(p)
if s_len < p_len:
return []
ans = []
s_count = [0] * 26
p_count = [0] * 26
for i in range(p_len):
s_count[ord(s[i]) - 97] += 1
p_count[ord(p[i]) - 97] += 1
if s_count == p_count:
ans.append(0)
for i in range(s_len - p_len):
s_count[ord(s[i]) - 97] -= 1
s_count[ord(s[i + p_len]) - 97] += 1
if s_count == p_count:
ans.append(i + 1)
return ans
作者:力扣官方题解
链接:https://leetcode.cn/problems/find-all-anagrams-in-a-string/solutions/1123971/zhao-dao-zi-fu-chuan-zhong-suo-you-zi-mu-xzin/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
2.减小储存空间,出相同-1,进相同+1,differ记录不同的个数
部分代码:
# 列表推导式的结果:生成一个布尔值列表,表示每个元素是否是非零值。
count = [1, 0, 2, 0, 3]
bool_list = [c != 0 for c in count]
print(bool_list) # 输出:[True, False, True, False, True]
# .count(True):计算布尔值列表中 True 的数量,即非零元素的数量。
differ = bool_list.count(True)
print(differ) # 输出:3
全部代码:
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
s_len, p_len = len(s), len(p)
if s_len < p_len:
return []
ans = []
count = [0] * 26
for i in range(p_len):
count[ord(s[i]) - 97] += 1
count[ord(p[i]) - 97] -= 1
differ = [c != 0 for c in count].count(True)
if differ == 0:
ans.append(0)
for i in range(s_len - p_len):
if count[ord(s[i]) - 97] == 1: # 窗口中字母 s[i] 的数量与字符串 p 中的数量从不同变得相同
differ -= 1
elif count[ord(s[i]) - 97] == 0: # 窗口中字母 s[i] 的数量与字符串 p 中的数量从相同变得不同
differ += 1
count[ord(s[i]) - 97] -= 1
if count[ord(s[i + p_len]) - 97] == -1: # 窗口中字母 s[i+p_len] 的数量与字符串 p 中的数量从不同变得相同
differ -= 1
elif count[ord(s[i + p_len]) - 97] == 0: # 窗口中字母 s[i+p_len] 的数量与字符串 p 中的数量从相同变得不同
differ += 1
count[ord(s[i + p_len]) - 97] += 1
if differ == 0:
ans.append(i + 1)
return ans
作者:力扣官方题解
链接:https://leetcode.cn/problems/find-all-anagrams-in-a-string/solutions/1123971/zhao-dao-zi-fu-chuan-zhong-suo-you-zi-mu-xzin/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
自己的做法:
O(N2Logn),因为排序,时间比较长
又是用双指针做的,感觉和滑动窗口异曲同工(不过双指针中间长度不固定,滑动窗口固定罢了)
感觉我丢return 【】的这部分丢的比它做法1多
写代码的时候出现的问题:for循环的数量和缩进
class Solution(object):
def findAnagrams(self, s, p):
"""
:type s: str
:type p: str
:rtype: List[int]
"""
# 想法1:把所有p的排列组合列出来,进行搜索
# 想法2:把所有有字母的对应长度截取下来排序,看看和p是否不同
# 想法2的拓展:把每个字母都在p(集合)内的同等长度序列截下来,再判断
# 先丢一部分
s_set = set(s)
p_set = set(p)
for x in p_set:
if x not in s_set:
return []
# 双指针
a = 0
b = len(p)
p_sort = sorted(p)
l = []
while b <= len(s):
if s[a] in p_set:
for x in s[a+1:b]: # 错1
if x not in p_set:
break
if x == s[b-1]: # 错2
l1 = sorted(s[a:b])
if l1 == p_sort:
l.append(a)
a += 1
b += 1
return l
1. 时间复杂度更高(减了一个判断),但更好懂的代码
class Solution(object):
def findAnagrams(self, s, p):
"""
:type s: str
:type p: str
:rtype: List[int]
"""
# 想法1:把所有p的排列组合列出来,进行搜索
# 想法2:把所有有字母的对应长度截取下来排序,看看和p是否不同
# 想法2的拓展:把每个字母都在p(集合)内的同等长度序列截下来,再判断
# 先丢一部分
s_set = set(s)
p_set = set(p)
for x in p_set:
if x not in s_set:
return []
# 双指针
a = 0
b = len(p)
p_sort = sorted(p)
l = []
while b <= len(s):
if s[a] in p_set:
l1 = sorted(s[a:b])
if l1 == p_sort:
l.append(a)
a += 1
b += 1
return l