非定长滑动窗口(持续更新)

目录

[3. 无重复字符的最长子串](#3. 无重复字符的最长子串)

[3090. 每个字符最多出现两次的最长子字符串](#3090. 每个字符最多出现两次的最长子字符串)

[1493. 删掉一个元素以后全为 1 的最长子数组](#1493. 删掉一个元素以后全为 1 的最长子数组)


3. 无重复字符的最长子串

题目来源:3. 无重复字符的最长子串 - 力扣(LeetCode)

分析:

  1. 最优解法是使用滑动窗口(双指针)技术。
  2. 维护一个窗口left, right,右指针不断扩展窗口,当遇到重复字符时,左指针移动到重复字符的下一个位置。
  3. 可以使用哈希表记录每个字符最近出现的位置,这样能在O(1)时间内判断是否有重复并快速调整窗口。
  4. 整个过程中持续更新最大长度值。时间复杂度为O(n),空间复杂度为O(min(m,n)),其中m是字符集大小。

my code:

python 复制代码
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        res = 0
        dic = defaultdict(int)
        left = 0
        for right,ele in enumerate(s):
            dic[ele] += 1
            while dic[ele] > 1:
                dic[s[left]] -= 1
                left += 1
            res = max(res, right - left + 1)
        return res

注意:

  1. 非定长滑动窗口中,窗口的移动需要条件约束,当满足这个条件才能移动
  2. 同时要及时更新结果
  3. 非定长window中,移除的操作通常需要使用while,这样才能涵盖诸多情况的子序列组合

3090. 每个字符最多出现两次的最长子字符串

题目来源:3090. 每个字符最多出现两次的最长子字符串 - 力扣(LeetCode)

分析:该题与无重复字符最长子串逻辑相同,只需要把1改为2即可

解:

python 复制代码
class Solution:
    def maximumLengthSubstring(self, s: str) -> int:
        res = 0
        left = 0
        dic = defaultdict(int)
        for right,c in enumerate(s):
            dic[c] += 1
            while dic[c] > 2:
                dic[s[left]] -= 1
                left += 1
            res = max(res,right + 1 - left)
        return res

1493. 删掉一个元素以后全为 1 的最长子数组

题目来源:1493. 删掉一个元素以后全为 1 的最长子数组 - 力扣(LeetCode)

分析:

  1. 因为要求删掉一个元素后的子数组最大长度,所以窗口内允许存在至多一个0(非1元素)
  2. 可以使用字典来存储0元素个数
  3. 如果0元素个数大于 1 ,那么滑动窗口直至窗口内0元素数量等于1
  4. 子数组长度应该 right - left 而不再 +1 因为删掉了其中一个元素0

我的答案:

python 复制代码
class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        res = left = 0
        dic = defaultdict(int)
        for right,element in enumerate(nums):
            if element != 1:
                dic[element] += 1
            while dic[element] > 1:
                dic[nums[left]] -= 1
                left += 1
            res = max(res,right - left)
        return res

标准题解:

python 复制代码
class Solution:
    def longestSubarray(self, nums: List[int]) -> int:
        ans = cnt0 = left = 0
        for right, x in enumerate(nums):
            # 1. 入,nums[right] 进入窗口
            cnt0 += 1 - x  # 维护窗口中的 0 的个数
            while cnt0 > 1:  # 不符合题目要求
                # 2. 出,nums[left] 离开窗口
                cnt0 -= 1 - nums[left]  # 维护窗口中的 0 的个数
                left += 1
            # 3. 更新答案,注意不是 right-left+1,因为我们要删掉一个数
            ans = max(ans, right - left)
        return ans

1208. 尽可能使字符串相等

题目链接:1208. 尽可能使字符串相等 - 力扣(LeetCode)

分析:

  1. 内置函数可以将字符转换为对应的ascall
  2. abs内置函数是去绝对值
  3. 总开销是否大于maxCost作为移动窗口的条件

解答:

python 复制代码
class Solution:
    def equalSubstring(self, s: str, t: str, maxCost: int) -> int:
        res = left = 0
        ans = 0  # 记录开销
        for right,(s_c,t_c) in enumerate(zip(s,t)):
            # 当前位需要的开销
            ans_tmp = abs(ord(s_c) - ord(t_c))
            # 目前总开销
            ans += ans_tmp
            while ans > maxCost:
                # 开始移除做边
                ans -= abs(ord(s[left]) - ord(t[left]))
                left += 1
            res = max(res,right + 1 - left)
        return res
相关推荐
倒头就睡的小比特3 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼3 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光3 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark3 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her13 天前
并查集-听课笔记
笔记·算法·并查集
码流子3 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven3 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark3 天前
从算法设计模式看编程思维的抽象能力4
算法
2601_962218613 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法