当前位置: 首页 > news >正文

前缀和 之 哈希表 之 和 的奇偶与倍数

文章目录

  • 930.和相同的二元子数组
  • 523.连续的子数组和

  • 求解连续子数组的和的问题,常常会使用到这个前缀和的思路,当然当数组存在单调性的时候,可以考虑使用不定长滑动窗口,在这里解释一下,何为数组的和存在这个单调性?就是nums[i]>=0或者nums[i]<=0,就是最终这个窗口的和值是随着窗口的大小变大而窗口的和值是随着变大或者变小的
  • 当然,前缀和更能处理这种非单调性的问题,当出现子数组的和的某种性质的统计或者判断的时候,我们常常会使用到哈希表进行对应的存储

930.和相同的二元子数组

930.和相同的二元子数组

在这里插入图片描述

  • 这个题目有多种解法,由于存在这个nums[i]>=0,所以是存在这个单调性的问题,所以考虑使用滑动窗口,当然,由于这个是恰好型的问题,所以考虑使用两个至少型的计算进行转化
class Solution:
        # 定义嵌套方法,并不使用 self参数
    def numSub(self,nums:List[int],goal:int ) ->int :
        left = count = ans = 0
        for right,i in enumerate(nums):
            count+=i
            while count >= goal and left <= right:
                count-=nums[left]
                left+=1
            ans += left
        return ans

    def numSubarraysWithSum(self, nums: List[int], goal: int) -> int:
        # 打算使用越长越好的方法,求解出和 >= goal 和 >= goal+1的情况
        return self.numSub(nums,goal) - self.numSub(nums,goal+1)



  • 更加通用的方法是,使用这个前缀和+哈希表,对于子数组的和为goal,我们只需使用哈希表存储对应的前缀和的次数,对于子数组的和为goal,只需查询当前的cusum-goal是否存在哈希表中,如果存在,则加上对应的次数,最后再更新这个前缀出现的次数即可
from collections import defaultdict
class Solution:
    def numSubarraysWithSum(self, nums: List[int], goal: int) -> int:
        n = len(nums)
        # 子数组要求是和为goal的子数组的数目,我们只需不断累加,记录对应的累加和的出现次数
        cursum = 0
        store = defaultdict(int)
        store[0] += 1
        ans = 0
        for i,c in enumerate(nums):
            cursum += c 
            if cursum - goal in store:
                ans += store[cursum-goal]
            store[cursum]+=1
        return ans

523.连续的子数组和

523.连续的子数组和

在这里插入图片描述

  • 倍数的问题,就不是单纯存储这个前缀和的出现的次数了,仔细想想,得存储这个%k的余数的情况,因为两个同余数的前缀和作差,那么该子数组的和肯定是k的倍数,由于考虑的是长度问题,所以哈希表记录的是余数出现的位置的下标
class Solution:
    def checkSubarraySum(self, nums: List[int], k: int) -> bool:
        # 字典用于存储余数及其对应的索引,初始化为 {0: -1} 以处理从索引0开始的子数组
        remainder_dict = {0: -1}
        cumulative_sum = 0  # 累加和
        # 遍历数组中的每个元素
        for i, num in enumerate(nums):
            cumulative_sum += num  # 更新累加和
            rem = cumulative_sum % k  # 计算当前累加和对k的余数

            # 如果余数已经存在于字典中
            if rem in remainder_dict:
                # 检查当前子数组的长度是否至少为2
                if i - remainder_dict[rem] >= 2:
                    return True
            else:
                # 如果余数不存在,则记录当前余数对应的索引
                remainder_dict[rem] = i

        # 如果没有找到符合条件的子数组,返回False
        return False

相关文章:

  • MySQL InnoDB引擎的锁机制详解
  • 蓝桥杯每日一题
  • 汽车PKE无钥匙进入系统一键启动系统定义与原理
  • 需求文档(PRD,Product Requirement Document)的基本要求和案例参考:功能清单、流程图、原型图、逻辑能力和表达能力
  • 晶艺代理,100V3.5A高耐压LA1823完全替换MP9487--启烨科技有限公司
  • 第一章:Tailwind CSS基础与项目设置 - 第三节:GitHub界面分析 - 设计规范与布局系统
  • CSS 属性选择器详解
  • [C++面试] 标准容器面试点
  • 机器学习——深入浅出理解朴素贝叶斯算法
  • 一个简单的RPC示例:服务端和客户端
  • 【mysql】查事务进程
  • gstreamer之GstVideoDecoder源码剖析
  • Spark DataFrame、Dataset 和 SQL 解析原理深入解析(万字长文多张原理图)
  • 计算机二级web易错点(3)-选择题
  • qwen2.5总览
  • 基于 YOLOv8 的瓷砖缺陷检测:从数据准备到模型部署的全流程实战
  • 探索具身多模态大模型:开发、数据集和未来方向(下)
  • Python----数据分析(Pandas三:一维数组Series的数据操作:数据清洗,数据转换,数据排序,数据筛选,数据拼接)
  • 市长海报/ Mayor‘s posters
  • MySQL 锁
  • 为发期刊,高校学者偷贩涉密敏感数据!国安部披露间谍案细节
  • 《2025城市青年旅行消费报告》发布,解码青年出行特征
  • 谜语的强制力:弗洛伊德与俄狄浦斯
  • 巴基斯坦军方:印度袭击已致巴方31人死亡
  • 纪念苏联伟大卫国战争胜利80周年阅兵彩排,解放军仪仗队亮相
  • 8大类1000多支,中国红十字会已建成10万人规模救援队伍