**1. 无重复最长子串**
子串的话肯定是连续的序列,设置一个集合,遍历每一个字符,当这个字符在集合中的话,删除的是从左到这个字符的所有元素。如果不重复就加入到集合中。
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
if not s: return 0
left = 0
lookup = set()
n = len(s)
max_len = 0
cur_len = 0
for i in range(n):
cur_len += 1
while s[i] in lookup:
lookup.remove(s[left])
left += 1
cur_len -= 1
if cur_len > max_len : max_len = cur_len
lookup.add(s[i])
return max_len
s = Solution()
print(s.lengthOfLongestSubstring('abcabcbb'))
**2. 串联所有单词的子串**
# 给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。
#
# 注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。
#
# 输入:
# s = "barfoothefoobarman",
# words = ["foo","bar"]
# 输出:[0,9]
# 解释:
# 从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。
# 输出的顺序不重要, [9,0] 也是有效答案。
#思路:在字符串上移动长度为words长的窗口,步长为1遍历。
#如何去判断子串也是难点 再定义一个滑动窗口,长度为每个单词的长度(因为每个单词等长)将待检测的单词用一个字典表示,key代表单词 value代表数目。
#定义一个字典,如果检测到了就加到字典中 key为检测单词,value为数目。当value中的数目大于之前字典中单词value时,说明不符合,反之依次遍历步长为每个单词的长度。
from collections import Counter, defaultdict
class Solution(object):
def findSubstring(self, string, words):
output = []
if not string or not words:
return output
single_len = len(words[0])
words_len = len(words) * single_len #第一个滑动窗口的长度
for step in range(len(string) - words_len + 1):
wordstr = string[step: step + words_len] #每次截取的值
if self.judge(wordstr, words):
output.append(step)
return output
def judge(self, wordstr, words): #words 为题目中查找的词
single_word = len(words[0])
original = Counter(words) #统计words
count_dict = defaultdict(int)
for word_index in range(0, len(wordstr) , single_word): #single_word为滑动窗口步长,
new_word = wordstr[word_index:word_index + single_word]
if new_word in list(original.elements()): #如果滑动值在words中
count_dict[new_word] += 1
if count_dict[new_word] > original[new_word]:
return False
else:
return False
# for word, count in dict(original).items():
# if count != count_dict[word]:
# return False
if original != count_dict:
return False
return True
if __name__ == '__main__':
s = Solution()
a = s.findSubstring("a", ["a"])
print(a)
**利用列表表达式**
from collections import Counter
class Solution:
def findSubstring(self, s: str, words: List[str]) -> List[int]:
if not words: return []
pattern=Counter(words)
res=[]
wsLen=len(words)
wLen=len(words[0])
for i in range(len(s)-wLen*wsLen+1):
cur=[s[i+j*wLen:i+(j+1)*wLen] for j in range(wsLen)]
if Counter(cur)==pattern: res.append(i)
return res
**最小覆盖字符串**
from collections import Counter
class Solution:
def minWindow(self, s, t):
"""
:type s: str
:type t: str
:rtype: str
"""
if not t or not s:
return ""
# Dictionary which keeps a count of all the unique characters in t.
dict_t = Counter(t)
# Number of unique characters in t, which need to be present in the desired window.
required = len(dict_t)
# left and right pointer
l, r = 0, 0
# formed is used to keep track of how many unique characters in t are present in the current window in its desired frequency.
# e.g. if t is "AABC" then the window must have two A's, one B and one C. Thus formed would be = 3 when all these conditions are met.
formed = 0
# Dictionary which keeps a count of all the unique characters in the current window.
window_counts = {}
# ans tuple of the form (window length, left, right)
ans = float("inf"), None, None
while r < len(s):
# Add one character from the right to the window
character = s[r]
window_counts[character] = window_counts.get(character, 0) + 1
# If the frequency of the current character added equals to the desired count in t then increment the formed count by 1.
if character in dict_t and window_counts[character] == dict_t[character]:
formed += 1
# Try and contract the window till the point where it ceases to be 'desirable'.
while l <= r and formed == required:
character = s[l]
# Save the smallest window until now.
if r - l + 1 < ans[0]:
ans = (r - l + 1, l, r)
# The character at the position pointed by the `left` pointer is no longer a part of the window.
window_counts[character] -= 1
if character in dict_t and window_counts[character] < dict_t[character]:
formed -= 1
# Move the left pointer ahead, this would help to look for a new window.
l += 1
# Keep expanding the window once we are done contracting.
r += 1
return "" if ans[0] == float("inf") else s[ans[1] : ans[2] + 1]
滑动窗口-文本序列
最新推荐文章于 2022-07-28 11:02:04 发布