LeetCode-刷题记录-前缀和合集(本篇blog会持续更新哦~)

一、前缀和(Prefix Sum)算法概述

前缀和算法通过预先计算数组的累加和,可以在常数时间内回答多个区间和相关的查询问题,是解决子数组和问题中的重要工具。

在这里插入图片描述

它的基本思想是通过预先计算和存储数组的前缀和,可以在 O(1) 的时间复杂度内计算任意子数组的和。

在这里插入图片描述

  1. 定义
    • 对于数组 nums,其前缀和 prefix[i] 定义为从数组起始位置到第 i 个元素的累加和。

在这里插入图片描述

  • 具体公式:prefix[i] = nums[0] + nums[1] + ... + nums[i]
  1. 计算方法
    • 首先,创建一个额外的数组或哈希表,用来存储每个位置的前缀和。
    • 通过一次遍历数组,依次计算并填充这个数组或哈希表。

在这里插入图片描述

  1. 应用
    • 快速计算子数组和:通过前缀和,可以快速计算任意子数组的和。例如,子数组 nums[l...r] 的和可以通过 prefix[r] - prefix[l-1] 来计算,其中 lr 分别是子数组的左右边界。

在这里插入图片描述

  • 解决相关问题:例如,最大子数组和、和为特定值的子数组个数等问题,都可以通过前缀和算法高效解决。

在这里插入图片描述


二、前缀和习题合集

1. LeetCode 930 和相同的二元子数组

在这里插入图片描述

  • 思路:

假设原数组的前缀和数组为 sum,且子数组 (i,j] 的区间和为 goal,那么 sum[j]−sum[i]=goal。因此我们可以枚举 j ,每次查询满足该等式的 i 的数量。

用哈希表记录每一种前缀和出现的次数,假设我们当前枚举到元素 nums[j],我们只需要查询哈希表中元素 sum[j]−goal 的数量即可,这些元素的数量即对应了以当前 j 值为右边界的满足条件的子数组的数量。

  • pre[j] - pre[i]= goal —> pre[i] = pre[j] - goal

  • 如果存在前缀和为 pre[j] - goal(也就是pre[i])

  • 说明从某个位置 j 到当前位置 i 的子数组和为 goal

最后这些元素的总数量即为所有和为 goal 的子数组数量。

  • 代码:

class Solution {public int numSubarraysWithSum(int[] nums, int goal) {int n = nums.length; // 数组的长度Map<Integer,Integer> map = new HashMap<>(); // 使用哈希表来记录前缀和的出现次数int pre_J = 0; // 初始前缀和为0int ans = 0; // 计数器,用来记录符合条件的子数组个数for (int i = 0; i < n; i++) {map.put(preJ, map.getOrDefault(pre_J, 0) + 1); // 更新前缀和为 preJ 的出现次数pre_J += nums[i]; // 计算当前位置的前缀和//pre[j] - pre[i]= goal //pre[i] = pre[j] - goal// 计算满足条件的子数组个数// 如果存在前缀和为 pre[j] - goal(也就是pre[i])//说明从某个位置 j 到当前位置 i 的子数组和为 goalans += map.getOrDefault(pre_J - goal, 0);}return ans; // 返回符合条件的子数组个数}
}

2. LeetCode 560 和为K的子数组

在这里插入图片描述

  • 这里咋一看好像是可以用滑动窗口哈 ,但是发现数据里有负数。因为nums[i]可以小于0,也就是说右指针j向后移1位不能保证区间会增大,左指针i向后移1位也不能保证区间和会减小。

  • 思路 : 同上一题类似

前缀和 + 哈希

class Solution {public static int subarraySum(int[] nums, int k) {int n = nums.length; // 获取数组长度Map<Integer,Integer> map = new HashMap<>(); // 创建哈希表,用于存储前缀和及其出现次数int sum = 0; // 初始化前缀和为0int ans = 0; // 初始化结果为0map.put(sum,1); // 将初始的前缀和0放入哈希表,并设其出现次数为1// 遍历数组for(int num : nums){sum += num; // 计算当前位置的前缀和// 如果哈希表中存在前缀和为sum-k的项,则说明存在和为k的子数组 sum - (sum-k) = kif(map.containsKey(sum - k)){ans += map.get(sum - k); // 更新结果,累加前缀和为sum-k的子数组数量}map.put(sum, map.getOrDefault(sum, 0) + 1); // 更新哈希表,将当前前缀和放入,并更新出现次数}return ans; // 返回结果}
}
  • 初始时,将前缀和为 0 放入哈希表 map 中,表示在初始状态下存在一个前缀和为 0 的情况,出现次数为 1。

  • 如果 map 中存在 sum - k,则说明从之前的某个位置到当前位置的子数组的和为 k。这是因为 sum - (sum - k) = k

  • 如果存在这样的前缀和,则将该前缀和的出现次数累加到 ans 中。


3. LeetCode 523 连续的子数组和

在这里插入图片描述

在这里插入图片描述

  • 这里要用到数学知识——同余定理

在这里插入图片描述

  1. 前缀和的定义:preSum[i] 表示 nums 数组从 0 到 i 的元素之和。

    • 如果存在一个子数组 nums[j..i] (j < i),其和是 k 的倍数,则 preSum[i] - preSum[j-1] 必须是 k 的倍数。
  2. 利用余数的性质(同余定理)

    • 如果 preSum[i]preSum[j-1]k 取余得到相同的结果,即 (preSum[i] - preSum[j-1]) % k == 0,则存在这样的子数组。
    • a%k = b%k ,则 (a-b)%k =0 满足条件

在这里插入图片描述

  1. 使用哈希表记录余数: 使用哈希表来记录每个余数第一次出现的位置。

class Solution {public boolean checkSubarraySum(int[] nums, int k) {int n = nums.length;int[] pre = new int[n + 1];for (int i = 1; i <= n; i++) {pre[i] = pre[i - 1] + nums[i - 1]; // 计算前缀和}Set<Integer> set = new HashSet<>();for (int i = 2; i <= n; i++) {set.add(pre[i - 2] % k); // 将前缀和前两项的同余结果加入集合if (set.contains(pre[i] % k)) return true; // 如果当前前缀和对k取模的结果在集合中已经存在,说明找到了符合条件的子数组}return false; // 如果遍历完没有找到符合条件的子数组,返回false}
}

更新于:

在这里插入图片描述

本篇blog会持续更新哦~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/42159.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

7.8作业

一、思维导图 二、 1】按值修改 2】按值查找&#xff0c;返回当前节点的地址 &#xff08;先不考虑重复&#xff0c;如果有重复&#xff0c;返回第一个&#xff09; 3】反转 4】销毁链表 //按值修改 int value_change(linklistptr H,datatype e,int value) {if(HNULL||empty(H…

Greenplum(二)【SQL】

前言 Greenplum 的剩余部分主要其实主要就是 DDL 和之前学的 MySQL 不大一样&#xff0c;毕竟 Greenplum 是基于 PostgreSQL 数据库的&#xff0c;不过那些 DML 和 MySQL、Hive 基本上大差不差&#xff0c;所以就没有必要浪费时间了。 1、DDL 1.1、库操作 1.1.1、创建数据库…

python爬虫加入进度条

安装tqdm和requests库 pip install tqdm -i https://pypi.tuna.tsinghua.edu.cn/simplepip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple带进度条下载 import time # 引入time模块&#xff0c;用于处理时间相关的功能 from tqdm import * # 从tqdm包中…

【AI大模型】赋能儿童安全:楼层与室内定位实践与未来发展

文章目录 引言第一章&#xff1a;AI与室内定位技术1.1 AI技术概述1.2 室内定位技术概述1.3 楼层定位的挑战与解决方案 第二章&#xff1a;儿童定位与安全监控的需求2.1 儿童安全问题的现状2.2 智能穿戴设备的兴起 第三章&#xff1a;技术实现细节3.1 硬件设计与选择传感器选择与…

SpringSecurity中文文档(Servlet Authorization Architecture )

Authorization 在确定了用户将如何进行身份验证之后&#xff0c;还需要配置应用程序的授权规则。 Spring Security 中的高级授权功能是其受欢迎的最有说服力的原因之一。无论您选择如何进行身份验证(无论是使用 Spring Security 提供的机制和提供者&#xff0c;还是与容器或其…

两张图片合并(右上角添加水印,兼容矢量图)保留原来的颜色

无缝合并两张图片&#xff08;封面右上角添加logo&#xff09;-- opencv &#xff1a; 进行添加logo(水印)由于使用了cv2.seamlessClone&#xff0c;cv2.seamlessClone使用了泊松克隆&#xff08;Poisson Cloning&#xff09;&#xff0c;会根据周围的颜色信息进行颜色调整&…

three-tile 一个开源的轻量级三维瓦片库

three-tile 介绍 three-tile 是一个开源的轻量级三维瓦片库&#xff0c;它基于threejs使用typescript开发&#xff0c;提供一个三维地形模型&#xff0c;能轻松给你的应用增加三维瓦片地图。 源码&#xff1a;https://github.com/sxguojf/three-tile 示例&#xff1a;https:/…

【TB作品】51单片机 Proteus仿真 00013红外proteus仿真循迹避障小车

实验报告&#xff1a;智能小车系统设计与实现 一、背景介绍 本实验旨在设计并实现一个基于STC89C52单片机控制的智能小车系统。该系统通过超声波传感器进行避障&#xff0c;通过红外接收器实现远程控制&#xff0c;同时具备循迹功能。整个系统的核心是单片机&#xff0c;它通…

YOLOv10改进 | 损失函数篇 | InnerIoU、InnerSIoU、InnerWIoU、FocusIoU等损失函数

一、本文介绍 本文给大家带来的是YOLOv10最新改进&#xff0c;为大家带来最近新提出的InnerIoU的内容同时用Inner的思想结合SIoU、WIoU、GIoU、DIoU、EIOU、CIoU等损失函数&#xff0c;形成 InnerIoU、InnerSIoU、InnerWIoU、等新版本损失函数&#xff0c;同时还结合了Focus和…

LeetCode42(接雨水)[三种解法:理解动态规划,双指针,单调栈]

接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 这是一道困难题,难度确实有点层次.我们先来朴素思想走一波. 要求能接多少雨水,我们可以具化到每个硅谷,每个硅谷能存多少雨水,那么答案就是每个…

PDA:Prompt-based Distribution Alignment for Unsupervised Domain Adaptation

文章汇总 式中&#xff0c; y s y^s ys表示源域数据的one-hot ground-truth&#xff0c; K K K为类数&#xff0c; w i w_i wi​和 z ~ s \tilde{z}_s z~s​分别表示源域经过提示调优的最终文本表示和最终图像表示的第 i i i类。 同理&#xff0c;为了进一步利用目标领域的数据…

防火墙详解(USG6000V)

0、防火墙组网模式 防火墙能够工作在三种模式下分别是路由模式、透明模式、旁路检测模式、混合模式 0.1、路由模式 路由模式&#xff1a;防火墙全部以第三层对外连接&#xff0c;即接口具有IP 地址。一般都用在防火墙是边界的场景下 防火墙需要的部署/配置&#xff1a; 接…

10、DDD分层架构

微服务架构模型有很多种&#xff0c;例如洋葱架构、CQRS和六边形架构等。虽然这些架构模式提出的时代和背景不同&#xff0c;但其核心理念都是为了设计出“高内聚&#xff0c;低耦合”的微服务&#xff0c;轻松实现微服务的架构演进。DDD分层架构的出现&#xff0c;使微服务的架…

【uniapp-ios】App端与webview端相互通信的方法以及注意事项

前言 在开发中&#xff0c;使用uniapp开发的项目开发效率是极高的&#xff0c;使用一套代码就能够同时在多端上线&#xff0c;像笔者之前写过的使用Flutter端和webview端之间的相互通信方法和问题&#xff0c;这种方式本质上实际上是h5和h5之间的通信&#xff0c;网上有非常多…

物联网实训室建设可行性报告

一、建设物联网实训室的目的和意义 随着信息技术的快速发展&#xff0c;物联网&#xff08;IoT&#xff09;已成为推动社会进步和经济发展的关键技术之一。物联网技术的集成应用&#xff0c;不仅能够提高生产效率&#xff0c;还能促进智慧城市、智能家居、智能农业等多个领域的…

python04——类(基础new)

类其实也是一种封装的思想&#xff0c;类就是把变量、方法等封装在一起&#xff0c;然后可以通过不同的实例化对其进行调用操作。 1.类的定义 class 类名&#xff1a; 变量a def __init__ (self,参数2&#xff0c;参数2...)&#xff1a;初始化函数&#xff01;&#xff01;&…

简单实现联系表单Contact Form自动发送邮件

如何实现简单Contact Form自动邮件功能&#xff1f;怎样简单设置&#xff1f; 联系表单不仅是访客与网站所有者沟通的桥梁&#xff0c;还可以收集潜在客户的信息&#xff0c;从而推动业务的发展。AokSend将介绍如何简单实现一个联系表单&#xff0c;自动发送邮件的过程&#x…

【游戏客户端】大话slg玩法架构(一)滚动基类

【游戏客户端】大话slg玩法架构&#xff08;一&#xff09;滚动基类 大家好&#xff0c;我是Lampard家杰~~ 今天我们兑现诺言&#xff0c;给大家分享SLG玩法的实现j架构&#xff0c;关于SLG玩法的介绍可以参考这篇上一篇文章&#xff1a;【游戏客户端】制作率土之滨Like玩法 PS…

机器学习统计学基础 - 最大似然估计

最大似然估计&#xff08;Maximum Likelihood Estimation, MLE&#xff09;是一种常用的参数估计方法&#xff0c;其基本原理是通过最大化观测数据出现的概率来寻找最优的参数估计值。具体来说&#xff0c;最大似然估计的核心思想是利用已知的样本结果&#xff0c;反推最有可能…

binutils ifunc 流程图

上图是x86 binutils 的流程图。 函数说明_bfd_x86_elf_link_hash_table_createInit local STT_GNU_IFUNC symbol hash.elf_x86_64_check_relocsAdd support for handling STT_GNU_IFUNC symbols_bfd_elf_x86_get_local_sym_hashFind and/or create a hash entry for local sym…