基础算法(4)——前缀和

1. 前缀和

题目描述:

解法一:暴力解法

直接模拟实现题目流程即可

时间复杂度为O(N*q),根据题目给出的条件q <= 10^{5},肯定会超时

解法二:前缀和(适用题型:快速 求出数组中某一个 连续区间 的 

时间复杂度:O(q)+O(n)

算法思路:

细节问题:为什么数组下标从 1 开始

当数组下标从 0 开始,dp[l - 1] 就成了 dp[-1] 造成数组越界异常

因此数组下标从 1 开始,若是数组下标从 0 开始时,需要处理边界情况

代码实现:

import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);//1.读入数据int n = in.nextInt();int q = in.nextInt();int[] arr = new int[n + 1];for (int i = 1; i < n + 1; i++) {arr[i] = in.nextInt();}//2.预处理一个前缀和数组long[] dp = new long[n + 1]; //防溢出dp[1] = arr[1];for (int j = 2; j < n + 1; j++) {dp[j] += dp[j - 1] + arr[j];}//3.使用前缀和数组while (q > 0) {int l = in.nextInt();int r = in.nextInt();System.out.println(dp[r] - dp[l - 1]);q--;}}
}

2. 二维前缀和

题目描述:

解法一:暴力解法(模拟)

时间复杂度:O(n*m*q),会超时

解法二:前缀和

时间复杂度:O(m*n)+O(q)

算法思路:

代码实现:

import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);//1.读入数据int n = in.nextInt();int m = in.nextInt();int q = in.nextInt();int[][] arr = new int[n + 1][m + 1];for (int i = 1; i < n + 1; i++) {for (int j = 1; j < m + 1; j++) {arr[i][j]= in.nextInt();}}//2.预处理一个前缀和矩阵long[][] dp = new long[n + 1][m + 1];for (int i = 1; i < n + 1; i++) {for (int j = 1; j < m + 1; j++) {dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + arr[i][j] - dp[i - 1][j - 1];}}//3.使用前缀和矩阵while (q > 0) {int x1 = in.nextInt();int y1 = in.nextInt();int x2 = in.nextInt();int y2 = in.nextInt();System.out.println(dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1]);q--;}}
}

3. 寻找数组的中心下标

题目描述:

解法:前缀和

算法思路:

从中心下标的定义可知,除中心下标的元素外,该元素左边的【前缀和】等于该元素右边的【后缀和】

因此我们可以先预处理出来两个数组,一个表示前缀和,一个表示后缀和

然后用一个 for 循环枚举可能的中心下标,判断每一个位置的【前缀和】以及【后缀和】,如果二者相等,就返回当前下标

代码实现:

class Solution {public int pivotIndex(int[] nums) {int n = nums.length;//f[i] 表示:[0, i - 1] 区间所有元素的和//g[i] 表示:[i + 1, n - 1] 区间所有元素的和int[] f = new int[n]; //前缀和数组int[] g = new int[n]; //后缀和数组//预处理前缀和后缀和数组(优化前)//这里当i等于0时,f[0]本来就是0,没必要多加判断,直接从1位置开始遍历即可// for (int i = 0; i < n; i++) {//     if (i == 0) {//         f[i] = 0;//     } else {//         f[i] = f[i - 1] + nums[i - 1];//     }// }//当i等于n-1时本来就是0,无需处理,直接从n-2处开始遍历即可// for (int i = n - 1; i >= 0; i--) {//     if (i == n - 1) {//         g[i] = 0;//     } else {//         g[i] = g[i + 1] + nums[i + 1];//     }// }//预处理前缀和后缀和数组(优化后)for (int i = 1; i < n; i++) {f[i] = f[i - 1] + nums[i - 1];}for (int i = n - 2; i >= 0; i--) {g[i] = g[i + 1] + nums[i + 1];}//使用前后缀和数组进行判断for (int i = 0; i < n; i++) {if (f[i] == g[i]) {return i;}}return -1;}
}

4. 除自身以外数组的乘积

题目描述:

解法:前缀积

算法思路:

根据题意,对于每一个位置的最终结果 answer[i] 都由两部分组成:

第一部分:nums[0] * nums[1] * nums[2] * ... * nums[i - 1]

第二部分:nums[i + 1] * nums[i + 2] * ... * nums[n - 1]

可以利用前缀和的思想,使用两个数组 f 和 g 分别处理出来两个信息:

代码实现:

class Solution {public int[] productExceptSelf(int[] nums) {int n = nums.length;//f[i] 表示[0, i-1] 区间内所有元素的乘积//g[i] 表示[i+1, n-1] 区间内所有元素的乘积int[] f = new int[n];int[] g = new int[n];int[] answer = new int[n];//细节问题,这两个下标处的值需设为1,设为0的话任何数乘0都得0了f[0] = 1;g[n - 1] = 1;//预处理前缀积和后缀积for (int i = 1; i < n; i++) {f[i] = f[i - 1] * nums[i - 1];}for (int i = n - 2; i >= 0; i--) {g[i] = g[i + 1] * nums[i + 1];}//处理结果数组for (int i = 0; i < n; i++) {answer[i] = f[i] * g[i];}return answer;}
}

5. 和为 K 的子数组

题目描述:

解法一:暴力枚举

时间复杂度:O(N)

算法思路:

解法二:前缀和

算法思路:

代码实现:

class Solution {public int subarraySum(int[] nums, int k) {Map<Integer, Integer> hash = new HashMap<Integer, Integer>();hash.put(0, 1); //对应整个数组元素和为 k 的情况int sum = 0; //记录上一个位置的元素和int ret = 0; //记录前缀和为 sum - k 出现的次数for (int x : nums) {sum += x; //计算当前位置的前缀和ret += hash.getOrDefault(sum - k, 0); //统计结果hash.put(sum, hash.getOrDefault(sum, 0) + 1); //把当前的前缀和放入哈希表}return ret;}
}

6. 和可被 K 整除的子数组

题目描述:

知识补充:

算法思路:

代码实现:

class Solution {public int subarraysDivByK(int[] nums, int k) {Map<Integer, Integer> hash = new HashMap<Integer, Integer>();hash.put(0 % k, 1);int sum = 0; //标记前一个位置的前缀和int ret = 0; //表示最终结果for (int x : nums) {sum += x; //计算当前位置的前缀和int r = (sum % k + k) % k;ret += hash.getOrDefault(r, 0); //统计结果hash.put(r, hash.getOrDefault(r, 0) + 1);}return ret;}
}

7. 连续数组

题目描述:

解法:前缀和 + 哈希表

代码实现:

class Solution {public int findMaxLength(int[] nums) {Map<Integer, Integer> hash = new HashMap<>();hash.put(0, -1); //默认存在一个前缀和为 0 的情况int sum = 0;int ret = 0;for (int i = 0; i < nums.length; i++) { //此处要求下标,所以不能用 foreach//计算当前位置前缀和//无需修改原数组,仅需判断当前位置为 0 时,加上 -1 即可sum += (nums[i] == 0 ? -1 : 1);if (hash.containsKey(sum)) { //判断哈希表中是否存在前缀和ret = Math.max(ret, i - hash.get(sum));} else { //若哈希表中不存在前缀和,则更新hash.put(sum, i);}}return ret;}
}

实例:

8. 矩阵区域和

题目描述:

题目解析:

解法:二维前缀和

二维前缀和递推公式推导:

使用前缀和

算法思路:

此处将 answer 简写为 ans

第一步:当我们要求 ans[i][j] 时,仅需知道其对应的 x1、y1、x2、y2

第二步:下标的映射关系

代码实现:

class Solution {public int[][] matrixBlockSum(int[][] mat, int k) {int m = mat.length;int n = mat[0].length;//1.预处理前缀和矩阵int[][] dp = new int[m + 1][n + 1]; //此处 +1 操作就是为 dp 表增加一行一列for (int i = 1; i <= m; i++) { //dp 表从(1,1)开始for (int j = 1; j <= n; j++) {dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + mat[i - 1][j - 1];}}//2.使用int[][] ret = new int[m][n];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {int x1 = Math.max(0, i - k) + 1;int y1 = Math.max(0, j - k) + 1;int x2 = Math.min(m - 1, i + k) + 1;int y2 = Math.min(n - 1, j + k) + 1;ret[i][j] = dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1];}}return ret;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

车路云一体化大模型数据治理方案

车路云一体化大模型数据治理解决方案 "杭州市发改委已批复了杭州交通投资集团的智能网联汽车“车路云一体化”试点项目。这一批复体现了其对该项目可行性研究报告的肯定&#xff0c;预示着杭州市在智能驾驶领域的进一步发展。" 2024年6月18日&#xff0c;第十一届国…

WGS1984快速度确定平面坐标系UTM分带(快速套表、公式计算、软件范围判定)

之前我们介绍了坐标系3带6带快速确定带号及中央经线&#xff08;快速套表、公式计算、软件范围判定&#xff09;就&#xff0c;讲的是CGCS2000 高斯克吕格的投影坐标系。 那还有我们经常用的WGS1984的平面坐标系一般用什么投影呢? 对于全球全国的比如在线地图使用&#xff1a…

面向未来的算力网络连接发展趋势分析

面向未来的算力网络连接发展特点与实践 AI算力研究&#xff1a;英伟达B200再创算力奇迹&#xff0c;液冷、光模块持续革新 英伟达隆重宣布新一代Blackwell架构&#xff0c;华为对GPU算力需求高达百万片。 英伟达发布的GB200 NVL72 机架级系统内部包括 72 个 Blackwell GPU 和…

【排序算法】插入排序_直接插入排序、希尔排序

文章目录 直接插入排序直接插入排序的基本思想直接插入排序的过程插入排序算法的C代码举例分析插入排序的复杂度分析插入排序的优点 希尔排序希尔排序&#xff08;Shell Sort&#xff09;详解希尔排序的步骤&#xff1a;希尔排序的过程示例&#xff1a;希尔排序的C语言实现举例…

S3C2440定时器

ee一、构造 二、设置相关位 1、MPLLCON寄存器&#xff08;配置MPLL寄存器&#xff0c;进行倍频&#xff09; 根据下列表格的想要输出的频率进行选择&#xff0c;选择完毕之后&#xff0c;对该寄存器进行设置 2、时钟分频控制&#xff08;CLKDIVN&#xff09;寄存器 根据不…

CSP-J 2024 入门组初赛第一轮初赛试题及答案解析

CSP-J 2024 入门组初赛第一轮初赛试题及答案解析 一、 单项选择题&#xff08;共15题&#xff0c;每题2分&#xff0c;共计30分&#xff1a;每题有且仅有一个正确选项&#xff09; 1 32 位 int 类型的存储范围是&#xff08; &#xff09; A -2147483647 ~ 2147483647 B -21…

第十四章:html和css做一个心在跳动,为你而动的表白动画

💖 让心跳加速,传递爱意 💖 在这个特别的时刻,让爱在跳动中绽放!🌟 无论是初次相遇的心动,还是陪伴多年的默契,我们的心总在为彼此跳动。就像这颗炙热的爱心,随着每一次的跳动,传递着满满的温暖与期待。 在这个浪漫的季节,让我们一同感受爱的律动!无论你是在…

【深度学习】(4)--卷积神经网络

文章目录 卷积神经网络一、画面不变性二、图像识别三、卷积网络结构1. 原理2. 卷积层3. 池化层4. 全连接层 四、感受野 总结 卷积神经网络 卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;简称CNN&#xff09;是一种深度学习模型&#xff0c;特别适用于处理…

基于SpringBoot+Vue+MySQL的校园一卡通系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着现代社会的快速发展&#xff0c;校园一卡通已成为大学生活中不可或缺的一部分。它不仅承载着校园消费的功能&#xff0c;还集成了学生身份证明、图书馆借阅、门禁系统等多种服务。然而&#xff0c;传统的一卡通管理系统往往…

设计模式之策略模式例题

答案&#xff1a;A 知识点&#xff1a; 策略模式又叫模板方法模式 它的意图是定义一个操作中的算法骨架。而将一些步骤延迟到子类中&#xff0c;使得子类可以不改变一个算法的结构即可重新定义算法的某些特定步骤

Elasticsearch——介绍、安装与初步使用

目录 1.初识 Elasticsearch1.1.了解 ES1.1.1.Elasticsearch 的作用1.1.2.ELK技术栈1.1.3.Elasticsearch 和 Lucene1.1.4.为什么不是其他搜索技术&#xff1f;1.1.5.总结 1.2.倒排索引1.2.1.正向索引1.2.2.倒排索引1.2.3.正向和倒排 1.3.Elasticsearch 的一些概念1.3.1.文档和字…

大模型LLM对话模拟器Dialogue Simulator Visualization可视化工具

伴随着生成式人工智能技术发展&#xff0c;进2年涌现出大语言模型LLM/Agent系统/AI推理等众多方向的技术项目和论文。其中对话系统&#xff0c;智能体交互是用户通过UX界面和AI系统进行交互&#xff0c;这种交互有时候也是多模态&#xff08;用户输入文字/语音/图像&#xff09…

MySQL高阶1919-兴趣相同的朋友

题目 请写一段SQL查询获取到兴趣相同的朋友。用户 x 和 用户 y 是兴趣相同的朋友&#xff0c;需满足下述条件&#xff1a; 用户 x 和 y 是朋友&#xff0c;并且用户 x and y 在同一天内听过相同的歌曲&#xff0c;且数量大于等于三首. 结果表 无需排序 。注意&#xff1a;返…

用最通俗易懂的语言和例子讲解三维点云

前言&#xff1a; 我整体的学习顺序是看的按B站那“唯一”的三维点云的视频学习的&#xff08;翻了好久几乎没有第二个...&#xff09;对于深度学习部分&#xff0c;由于本人并没有进行学习&#xff0c;所以没有深究。大多数内容都进行了自己的理解并找了很多网络的资源方便理解…

论文阅读:A Generalization of Transformer Networks to Graphs

论文阅读&#xff1a;A Generalization of Transformer Networks to Graphs 1 摘要2 贡献Graph TransformerOn Graph Sparsity&#xff08;图稀疏&#xff09;On Positional Encodings&#xff08;位置编码&#xff09;3 Graph Transformer Architecture&#xff08;架构&#…

阿里HPN-用于大型语言模型训练的数据中心网络

阿里巴巴HPN:用于大型语言模型训练的数据中心网络 探索大规模语言模型训练新方法&#xff1a;阿里巴巴HPN数据中心网络论文。 摘要 本文介绍了阿里云用于大型语言模型(LLM)训练的数据中心网络HPN。由于LLM和一般云计算之间的差异(例如&#xff0c;在流量模式和容错性方面)&…

一份热乎的阿里25届数据分析面试题

目录 阿里巴巴25届数分面试题 想要获取答案&#xff0c;想进一步了解SQL这门艺术语言的&#xff0c;可以订阅我的专栏数字化建设通关指南&#xff0c;将在该专栏进行详细解析。 专栏 原价99&#xff0c;现在活动价39.9&#xff0c;按照阶梯式增长&#xff0c;还差3个名额将上…

如何备份SqlServer数据库

第一步&#xff1a;登录你要备份的服务器数据库ssms 第二步&#xff1a;选择你要备份的数据库 此处已PZ-SJCS 数据库为例 右键该数据库-->任务-->备份 第三步&#xff1a;选择你备份的类型备份组件等&#xff0c;目标磁盘 &#xff0c;点击添加选择将你备份的文件备份那…

kubernetes网络(一)之calico详解

摘要 本文介绍Kubernetes最流行的网络解决方案calico。 kubernetes中不同宿主上的pod需要相互通信&#xff0c;如果按TCP/IP协议分层进行分类&#xff1a; 二层方案&#xff1a;flannel的udp和vxlan模式 三层方案&#xff1a;flannel的host-gw模式&#xff1b;calico的IPIP模…

pod介绍与配置

1、pod概念介绍 Pod 是 kubernetes 基本调度单位。每个 Pod 中可以运 行一个或多个容器&#xff0c;共享 Pod 的文件系统、IP 和网络等资源&#xff0c;每个 Pod 只有一个 IP。 2、使用 yaml或json 文件创建 Pod 声明式文件方式创建 Pod&#xff0c;支持 yaml 和 json 1&…