leetcode 滑动窗口 3 567

滑动窗口

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]]
计数器可以为负数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值