滑动窗口
points:
1.设置一个窗口,不断地滑动,满足条件时,窗口扩大,不满足条件时,窗口重置。
2.不满足条件时,窗口的重置,有两种情况,一种是重置至变化前,一种是删除头部元素,两个条件要判断好。
leetcode 3
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
这题思路很简单
point:
1.设置窗口:res = ‘’ 和指针cur
满足的条件为: if s[cur] not in res: res+=s[cur] cur+=1
2.重置条件: if s[cur] in res: res = res[1:] (此时不需要cur+=1,因为res[1]不知道是否和不满足条件的s[cur]重复)
代码如下:
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
n = len(s)
length = 0
cur = 0
res = ''
temp_len = 0
while cur < n:
if s[cur] not in res:
res+=s[cur]
temp_len += 1
cur += 1
else:
length = max(length,temp_len)
res = res[1:]
temp_len = len(res)
length = max(length,temp_len)
return length
leetcode 567
给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。
换句话说,s1 的排列之一是 s2 的 子串 。
示例
输入:s1 = “ab” s2 = “eidbaooo”
输出:true
解释:s2 包含 s1 的排列之一 (“ba”).
该题重点思路在于,如何判断排列组合
设置一个临时字符串 temp = ‘’
当collections.Counter(temp) == collections.Counter(s1) 时即可以满足题目的要求(也就是当各个字符统计数相同时,即满足s1的排列组合在s2中这一题目要求)
思路1:
point:
1.设置滑动窗口(res = ‘’)以及计数器(Count1 = collections.Counter(s1))
和指针cur
条件1:if s2[cur] in Count1: res+=s2[cur] cur+=1
条件2:if len(res) == len(s1): if collections.Counter(res) == Count1: return True
2.不满足条件时的重置条件,不满足条件1,将res = ‘’重置为空(因为要求s1的排列组合在s2中要连续存在,不能一个一个分布)
不满足条件2,则重置res = res[1:] (因为不满足条件2时,可能出现了重复元素,即一个一个删除头部元素判断即可,res = res[1:])
代码如下
class Solution:
def checkInclusion(self, s1: str, s2: str) -> bool:
count1 = collections.Counter(s1)
cur = 0
n2 = len(s2)
n1 = len(s1)
res = ''
while cur < n2:
if s2[cur] in count1:
res+=s2[cur]
cur += 1
else:
res = ''
cur += 1
if len(res) == n1:
if collections.Counter(res) == count1:
return True
else:
res = res[1:]
return False
思路2:
直接将窗口设置为 count2 = collections.Counter(s2[:len(s1)-1]
Count1 = collections.Counter(s1)
条件仍然为:count2 == Count1
设置遍历指针cur s1长度的最大遍历下标 n1 = len(s1) -1
当 n1<len(s2)时 不断往下遍历 count2[s2[n1]] += 1
判断条件 count2 == Count1
不满足时 count2[s2[cur]] -= 1 再加个判断是否有元素计数为0:
if couter2[s2[l]] == 0: del couter2[s2[l]]
代码如下
class Solution:
def checkInclusion(self, s1: str, s2: str) -> bool:
couter1 = collections.Counter(s1)
l = 0
r = len(s1) - 1
couter2 = collections.Counter(s2[0:r])
while r < len(s2):
couter2[s2[r]] +=1
if couter2 == couter1:
return True
couter2[s2[l]] -= 1
if couter2[s2[l]] == 0:
del couter2[s2[l]]
l+=1
r+=1
return False
关于collections.Counter()
1.couter2 = collections.Counter(s2[0:r]) #不会取到s2[r] 取到s2[r-1]
2.couter2[s2[r]] +=1 counter2中s2[r]的计数 +1
3.当计数器中有计数为0时 删除计数点 del couter2[s2[l]]
计数器可以为负数