力扣刷题总结一:模拟+哈希表+双指针+前缀和+滑动窗口

模拟

根据题目意思,捋清整个流程,使用代码去模拟整个流程

例题

种花问题
在这里插入图片描述

class Solution:
    def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool:
        # 模拟,在数组前后各添加1个0,从第1个元素到倒数第2个元素,判断元素是否为0且左右都为0则可插入
        flowerbed.insert(0,0)
        flowerbed.append(0)
        res=0
        for i in range(1,len(flowerbed)-1):
            if flowerbed[i]==0 and flowerbed[i-1]==0 and flowerbed[i+1]==0:
                res+=1
                flowerbed[i]=1
        return res>=n

哈希表

用于存储键值对的数据结构,Python的“字典”数据类型就是基于哈希表实现的。

作用:以空间换时间,快速判断一个元素是否出现在集合中

例题

K 和数对的最大数目
在这里插入图片描述

class Solution:
    def maxOperations(self, nums: List[int], k: int) -> int:
        # 使用字典统计每个数字的个数,配对成功则个数-1
        dt={}
        for i in nums:
            if i in dt:
                dt[i]+=1
            else:
                dt[i]=1
        res=0
        for i in nums:
            if dt[i]!=0:
                dt[i]-=1
                if dt.get(k-i,0)!=0:
                    res+=1
                    dt[k-i]-=1
        return res

双指针解法

class Solution:
    def maxOperations(self, nums: List[int], k: int) -> int:
        # 排序+双指针
        nums.sort()
        res=0
        l=0
        r=len(nums)-1
        while l<r:
            if nums[l]+nums[r]==k:
                res+=1
                l+=1
                r-=1
            elif nums[l]+nums[r]>k:
                r-=1
            else:
                l+=1
        return res

前缀和

数组前n个数之和

作用:求区间和

维护前缀和数组

nums=range(100)  # 需要求区间和的数组
n=len(nums)
preSum=[0]*(n+1)  # 初始化长度为n+1的前缀和数组
for i in nums:
	preSum[i+1]=preSum[i]+nums[i]  # 维护前缀和数组

例题

子数组最大平均数 I
在这里插入图片描述

class Solution:
    def findMaxAverage(self, nums: List[int], k: int) -> float:
        # 前缀和数组
        n=len(nums)
        if n==k:
            return sum(nums)/k
        preSum=[0]*(n+1)
        for i in range(n):
            preSum[i+1]=preSum[i]+nums[i]
        
        l=0
        res=float("-inf")
        for i in range(n-k+1):
            res=max(preSum[i+k]-preSum[i],res)
        return res/k

滑动窗口

滑动窗口,顾名思义,窗口大小可以不固定,使用左右指针,作为窗口的左右边界。

滑动窗口模板

def findSubArray(nums):
    N = len(nums) # 数组/字符串长度
    left, right = 0, 0 # 双指针,表示当前遍历的区间[left, right],闭区间
    sums = 0 # 用于统计 子数组/子区间 是否有效,根据题目可能会改成求和/计数
    res = 0 # 保存最大的满足题目要求的 子数组/子串 长度
    while right < N: # 当右边的指针没有搜索到 数组/字符串 的结尾
        sums += nums[right] # 增加当前右边指针的数字/字符的求和/计数
        while 区间[left, right]不符合题意: # 此时需要一直移动左指针,直至找到一个符合题意的区间
            sums -= nums[left] # 移动左指针前需要从counter中减少left位置字符的求和/计数
            left += 1 # 真正的移动左指针,注意不能跟上面一行代码写反
        # 到 while 结束时,我们找到了一个符合题意要求的 子数组/子串
        res = max(res, right - left + 1) # 需要更新结果
        right += 1 # 移动右指针,去探索新的区间
    return res

例题

最大连续1的个数 III
在这里插入图片描述

class Solution:
    def longestOnes(self, nums: List[int], k: int) -> int:
        # 滑动窗口
        n=len(nums)
        if n-sum(nums)<=k:  # 数组中0的总个数不大于容忍数,则可全部反转
            return n

        res=0
        l,r=0,0
        zeros=0  # 统计lr区间0的个数
        while r<n:
            if nums[r]==0:
                zeros+=1  # 区间中出现0,计数加1
            while zeros>k:  # 当区间中0的个数超过能容忍的反转数
                if nums[l]==0:  #如果左端点的值为0,则左端点右移,区间0的个数减1
                    zeros-=1
                l+=1  # 左端点右移
            res=max(res,r-l+1)
            r+=1  # 右端点右移
        return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值