python代码练习:滑动窗口

发布时间:2024年01月12日

前置:

  • 什么是滑动窗口
  • -inf 与 inf 用法
  • 理解滑动窗口主要弄清以下问题:
    • 1、窗口内的数据代表着什么?
    • 2、什么情况下需要扩展窗口右边界?
    • 3、什么情况下需要收缩窗口左边界?
    • 4、什么时候计算窗口大小?

题目1:长度最小的子数组

给定一个含有?n?个正整数的数组和一个正整数?target?。

找出该数组中满足其总和大于等于?target?的长度最小的?连续子数组?[numsl, numsl+1, ..., numsr-1, numsr]?,并返回其长度如果不存在符合条件的子数组,返回?0?。

from typing import List
class Solution:
    def minSubArrayLen(self, s: int, nums: List[int]) -> int:
            sum=0
            i=0
            temp = float('inf')
            for j in range(len(nums)):  # 遍历数组种每一个item,并累加
               sum+=nums[j]
               
               while sum>=s:    # 满足目标条件后,开始缩小窗口
                   L = j-i+1    
                   temp = min(temp,L)   
                   # 目标是计算sum>=s时的最小窗口程度,该目标与while条件一直,所以写在while里面
                   # 并在窗口左边界变化之前就计算窗口大小
                   sum-=nums[i]
                   i+=1
            if temp==float('inf') :return  0
            else:return temp

s=Solution()
print(s.minSubArrayLen(s=7,nums=[2,3,1,2,4,3]))
print(s.minSubArrayLen(s=4,nums=[1,4,4]))
print(s.minSubArrayLen(s=11,nums=[1,1,1,1]))

题目2:水果成篮

你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组?fruits?表示,其中?fruits[i]?是第?i?棵树上的水果?种类?。

你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:

  • 你只有?两个?篮子,并且每个篮子只能装?单一类型?的水果。每个篮子能够装的水果总量没有限制。
  • 你可以选择任意一棵树开始采摘,你必须从?每棵?树(包括开始采摘的树)上?恰好摘一个水果?。采摘的水果应当符合篮子中的水果类型。每采摘一次,你将会向右移动到下一棵树,并继续采摘。
  • 一旦你走到某棵树前,但水果不符合篮子的水果类型,那么就必须停止采摘。

给你一个整数数组?fruits?,返回你可以收集的水果的?最大?数目。

from collections import defaultdict
from typing import List
class Solution:
    def totalFruit(self, fruits: List[int]) -> int:
        a,i=len(fruits),0
        tree=0
        temp=0
        dic_tree = defaultdict(int)
        for j in range(a):  # 从左到右遍历每一个item,对每个item计数并将数据放入字典
            dic_tree[fruits[j]]+=1
            if dic_tree[fruits[j]] == 1:
                tree+=1 # 树的数量+到1时,意味着有新类型的树增加

            while tree>2:   # 树的类型超过2种时,开始缩小窗口
                dic_tree[fruits[i]]-=1
                if dic_tree[fruits[i]]==0:
                    tree-=1
                i+=1
            temp=max(temp,j-i+1)
            # 目标是计算tree<=2时窗口的大小,该目标与上文while条件不一致,所以写在while之外
        return temp

s=Solution()
print(s.totalFruit(fruits=[0,1,2,1]))
print(s.totalFruit(fruits=[1,2,1]))

题目3:无重复字符的最长子串

给定一个字符串?s?,请你找出其中不含有重复字符的?最长子串?的长度。

例1:s='ababaa'? 最长子串是 ab?,长度为2

例2:s='cccccc'? 最长子串是 c ,长度为1

例1:s='dvdf'? 最长子串是 vdf ,长度为3

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        temp_s=set()
        j=-1
        temp=0
        # 遍历窗口左边界
        for i in range(len(s)):
            #窗口右边界 in set,就会跳出while循环,从for开始继续遍历左边界(收缩窗口左边界)
            if i!=0:
                temp_s.remove(s[i-1])
            # 遍历窗口右边界
            # 窗口右边界一旦 not in set,就继续扩展右边界
            while j + 1 < len(s) and s[j + 1] not in temp_s:
                temp_s.add(s[j+1])
                j+=1
            temp = max(temp,j-i+1)
        return temp

s=Solution()
print(s.lengthOfLongestSubstring(s='dvdf'))

文章来源:https://blog.csdn.net/qq_40384309/article/details/135539153
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。