前缀和算法——优选算法

个人主页:敲上瘾-CSDN博客

个人专栏:游戏、数据结构、c语言基础、c++学习、算法

一、什么是前缀和?

        前缀和是指从数组的起始位置到某一位置(或矩阵的某个区域)的所有元素的和。这种算法通过预处理数组或矩阵,计算出每个位置(或区域)的前缀和,并将其存储在一个额外的数组或矩阵中,以便在后续查询中可以快速获取任意区间(或区域)的和。

        对于一维数组,可以使用递推公式dp[i] = dp[i - 1] + arr[i]来计算前缀和;对于二维矩阵,可以使用类似的递推公式,但需要考虑更多的边界情况。接下来我会用两个题来详细讲解前缀和的使用。

二、一维前缀和

和为k的子数组

        暴力解法: 分别以下标为0,1,... ,nums.size()-1为子数组的左边界依次往右延伸生成子数组。每次延伸需要判断子数组和是否为k。时间复杂度为O(N^2)代码如下:

class Solution {
public:int subarraySum(vector<int>& nums, int k){int ret=0;for(int i=0;i<nums.size();i++){int sum=0;for(int j=i;j<nums.size();j++){sum+=nums[j];if(sum==k) ret++;}}return ret;}
};

前缀和算法:

        如图要使子数组v的和等于目标值k则一定有sum2-sum1=k,即有sum1=sum2-k。那么我们可以计算一下该数组元素的前缀和并在计算过程中进行满足条件的子数组进行记录。注意这里是需要在计算前缀和的过程中进行统计,而不是完成所有前缀和计算后统计。记i=0,我们从下标i往右依次遍历。

需要考虑一下下面几个细节:

  • 因为这里需要往前查找前缀和所以为了提高效率,我们把i位置的前缀和结果累计在一个哈希表中,即unordered_map<int,int>它表示是<前缀和w,前缀和w出现的次数>。
  • 需要在元素存入哈希表之前进行统计目标子数组个数,也就是从左往右依次计算前缀和然后进行统计,最后才把该前缀和放入哈希表。这样可以不重不漏的完成计数。
  • 不需要单独再创建数组来储存前缀和,但是考虑要方便的记录i位置的前缀和,需要一个变量来储存前一个元素(即i-1)的前缀和。
  • 初始化:如果i位置的前缀和恰好为k,即sum2-k等于0,说明该位置到下标为0的这块区间都是满足条件的,是需要记录的,但是在它前面并没有一个位置的下标前缀和为0,所以需要将哈希表的前缀和为0的位置初始化为一次。
class Solution {
public:int subarraySum(vector<int>& nums, int k){unordered_map<int,int> hash;hash[0]=1;//初始化哈希表int result=0;int sum=0;//计算前缀和for(int i=0;i<nums.size();i++){sum+=nums[i];if(hash.count(sum-k))//如果hash表中有sum-k这个元素result+=hash[sum-k];//i位置的前缀和累计到哈希表中hash[sum]++;}return result;}
};

三、二维前缀和 

矩阵区域和

题目的意思是给你一个mat矩阵和,你需要返回的是一个同等规模的矩阵answer

其中矩阵answer[i][j]记录的是mat矩阵中(i,j)位置往四面八方延伸k个元素得到的子矩阵的和。

如下mat矩阵中不同的(i,j)位置,不同的k延伸得到的矩阵。

        这个题如果用暴力解法的话时间复杂度非常地高,而且有大量的重复计算,因为有重复计算所以可以往前缀和方面考虑。

首先我们可以额外开辟同规模的二维空间,记为dp,使用dp来储存从(i,j)到(0,0)位置为对角围成的矩阵的前缀和。

        如上(i,j)位置的前缀和dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+mat[i][j]。我们使用两层for循环就可以将所有位置的前缀和填到dp表中。

那么我们如何使用前缀和数组呢?我们来看下面面积A的计算。

        一块随机的面积若不考虑边界问题我们都可以把它分成四块已知前缀和的小矩阵。如上分解A=S1-S2-S3+S4,而这些面积已经储存在dp表中我们只需要找到它们的下标就能在dp表中找到。所以现在关键的是确定它们的下标位置,如下:

A=dp[x2][y2]-dp[x1][y2]-dp[x2][y1]+dp[x1][y1]。

对于一个m*n大小的矩阵的下标的查找:

x1=i-k,y1=j-k。边界处理:如果x1<0则dp[x1][y1]和dp[x1][y2]不用参与计算当做0处理。

x2=i+k,y2=j+k。边界处理:若x2>=m,则改为x2=m-1,若y2>=n则改为y2=n-1。

接下来我们就需要再开辟一块空间来储存结果,使用两个for循环将每个位置按公式

                dp[i][j]=dp[x2][y2]-dp[x1][y2]-dp[x2][y1]+dp[x1][y1]

计算,但要考虑边界情况,最后返回该矩阵即可。

class Solution {
public:vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k){int m=mat.size(),n=mat[0].size();//dp表的创建vector<vector<int>> dp(mat.size(),vector<int>(mat[0].size(),0)); for(int i=0;i<dp.size();i++){for(int j=0;j<dp[0].size();j++){int s1=0,s2=0,s3=0;if(i-1>=0) s1=dp[i-1][j];if(j-1>=0) s2=dp[i][j-1];if(i-1>=0&&j-1>=0) s3=dp[i-1][j-1];dp[i][j]=s1+s2-s3+mat[i][j];}}//dp表的使用vector<vector<int>> ret(m,vector<int>(n,0)); for(int i=0;i<m;i++){for(int j=0;j<n;j++){int s1=0,s2=0,s3=0,s4=0;//初始化面积//坐标计算int x1=i-k,y1=j-k,x2=i+k,y2=j+k;if(x2>=m) x2=m-1;if(y2>=n) y2=n-1;//面积计算s1=dp[x2][y2];if(x1>=0) s2=dp[x1][y2];if(y1>=0) s3=dp[x2][y1];if(x1>=0&&y1>=0) s4=dp[x1][y1];ret[i][j]=s1-s2-s2+s4;}}return ret;}
};

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

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

相关文章

【日志】编辑器开发——修复根据Excel表格数据生成Json文件和配置表代码报错

2024.10.15 又是蕉绿且摆烂的一天&#xff0c;不仅需要克制网瘾&#xff0c;还要努力学习&#xff0c;不然真的会被抛弃啊。但是我还是不想卷&#xff0c;给我的时间大概还有半年&#xff0c;突然好奇半年时间到底能学点什么或者做点什么。 【力扣刷题】 暂无 【数据结构】 …

Python入门笔记(七)

文章目录 第十五章. 下载数据15.1 csv文件15.2 json文件 第十六章. 使用API16.1 requests 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。 点击跳转&#xff1a;人工智能从入门到精通教程 本文电子版获取…

C++初阶学习第七弹——string的模拟实现

C初阶学习第六弹------标准库中的string类_c语言返回string-CSDN博客 通过上篇我们已经学习到了string类的基本使用&#xff0c;这里我们就试着模拟实现一些&#xff0c;我们主要实现一些常用到的函数。 目录 一、string类的构造 二、string类的拷贝构造 三、string类的析构函…

请求的响应----状态码分为五大类(爬虫)

前言 一个爬虫的成功与否&#xff0c;在于你是否拿到了想要的数据&#xff1b;一个请求的成功与否&#xff0c;在于响应的状态码&#xff0c;它标明了当前请求下这个响应的结果&#xff0c;是好还是坏。上节课程学习了HTTPS和HTTP协议的各自优势&#xff0c;本节课程进入到请求…

《Linux从小白到高手》综合应用篇:详解Linux系统调优之服务器硬件优化

List item 本篇介绍Linux服务器硬件调优。硬件调优主要包括CPU、内存、磁盘、网络等关键硬件组。 1. CPU优化 选择适合的CPU&#xff1a; –根据应用需求选择多核、高频的CPU&#xff0c;以满足高并发和计算密集型任务的需求。CPU缓存优化&#xff1a; –确保CPU缓存&#x…

前端学习-css的元素显示模式(十五)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 什么是元素显示模式 块元素 常见的块元素 块元素的特点 注意 行内元素 行内元素的特点 注意 行内块元素 行内块元素的特点 元素显示模式的转换 语法格…

SpringBoot高校学科竞赛平台:性能优化与实践

3系统分析 3.1可行性分析 通过对本高校学科竞赛平台实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本高校学科竞赛平台采用SSM框架&#xff0c;JAVA作为开发语…

Caffeine Cache解析(一):接口设计与TinyLFU

Caffeine is a high performance Java caching library providing a near optimal hit rate. 自动加载value, 支持异步加载基于size的eviction&#xff1a;frequency and recency基于时间的过期策略&#xff1a;last access or last write异步更新valuekey支持weak referenceva…

探索brpc:特性、使用场景与同步异步调用与封装示例

文章目录 前言特性使用场景brpc && grpc 对比 相关类与接口日志输出类与接口protobuf类与接口服务端类与接口客户端类与接口 使用同步调用 & 异步调用 封装封装思想代码 前言 brpc 是用 c语言编写的工业级 RPC 框架&#xff0c;常用于搜索、存储、机器学习、广告、…

Ansible自动化工具

一、Ansible概述 1.1 什么是Ansible Ansible 是一个开源的自动化工具&#xff0c;用于配置管理、应用程序部署和任务自动化。它让你可以通过编写简单的 YAML 文件&#xff08;剧本&#xff0c;Playbooks&#xff09;&#xff0c;轻松管理和配置多个服务器。Ansible 的特点是无…

4.redis通用命令

文章目录 1.使用官网文档2.redis通用命令2.1set2.2get2.3.redis全局命令2.3.1 keys 2.4 exists2.5 del(delete)2.6 expire - (失效时间)2.7 ttl - 过期时间2.7.1 redis中key的过期策略2.7.2redis定时器的实现原理 2.8 type2.9 object 3.生产环境4.常用的数据结构4.1认识数据类型…

【C++进阶】哈希表的介绍及实现

【C进阶】哈希表的介绍及实现 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;C&#x1f96d; &#x1f33c;文章目录&#x1f33c; 1. 哈希的概念 1.1 直接定址法 1.2 哈希冲突 1.3 负载因子 1.4 将关键字转为整数 2. 哈希函数 2.1 …

mqtt学习

简介&#xff1a; MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅模式的消息协议。它工作在 TCP/IP协议族上&#xff0c;是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议&#xff0c;为此&#xff0c;它需要一个消息中…

Android 未来可能支持 Linux 应用,Linux 终端可能登陆 Android 平台

近日&#xff0c;根据 android authority 的消息&#xff0c;Google 正在开发适用于 Android 的 Linux 终端应用&#xff0c;而终端应用可以通过开发人员选项启用&#xff0c;并将 Debian 安装在虚拟机中。 在几周前&#xff0c;Google 的工程师开始为 Android 开发新的 Termi…

推荐一个可以免费上传PDF产品图册的网站

​在数字化时代&#xff0c;企业将产品图册以PDF格式上传至网络&#xff0c;不仅便于客户浏览和下载&#xff0c;还能提升企业的专业形象。今天&#xff0c;就为您推荐一个可以免费上传PDF产品图册的网站——FLBOOK&#xff0c;轻松实现产品图册的在线展示。 1.注册登录&#x…

JAVA就业笔记7——第二阶段(4)

课程须知 A类知识&#xff1a;工作和面试常用&#xff0c;代码必须要手敲&#xff0c;需要掌握。 B类知识&#xff1a;面试会问道&#xff0c;工作不常用&#xff0c;代码不需要手敲&#xff0c;理解能正确表达即可。 C类知识&#xff1a;工作和面试不常用&#xff0c;代码不…

Mysql常用sql语句与刷题知识点

目录 1. 常用sql2. 刷题知识点 1. 常用sql #查询MySQL中所有的数据库 SHOW DATABASES; #查询当前正在使用的数据库 SELECT DATABASE();#普通创建&#xff08;创建已经存在的数据库会报错&#xff09; CREATE DATABASE 数据库名称; #创建并判断&#xff08;该数据库不存在才创建…

终端威胁检测与响应 (EDR) 技术研究

终端安全面临的挑战 从安全日常管理实践出发&#xff0c;终端安全的常见风险点是钓鱼攻击。因终端业务场景复杂&#xff0c;涉及即时通信软件、邮件等方式&#xff0c;如设置较严苛的拦截规则&#xff0c;则会造成较大的业务影响&#xff0c;且部分钓鱼通道为加密通道&#xf…

C_数据结构(栈) —— 栈的初始化、栈的销毁、入栈、出栈、bool类型判断栈是否为空、取栈顶元素、获取栈中有效元素个数

目录 一、栈 1、概念与结构 二、栈的实现 1、定义栈的结构 2、栈的初始化 3、栈的销毁 4、入栈 5、出栈 6、bool类型判断栈是否为空 7、取栈顶元素 8、获取栈中有效元素个数 三、完整实现栈的三个文件 Stack.h Stack.c test.c 一、栈 1、概念与结构 栈&#x…

K8s环境下使用sidecar模式对EMQX的exhook.proto 进行流量代理

背景 在使用emqx作为mqtt时需要我们需要拦截client的各种行为&#xff0c;如连接&#xff0c;发送消息&#xff0c;认证等。除了使用emqx自带的插件机制。我们也可以用多语言-钩子扩展来实现这个功能&#xff0c;但是目前emqx仅仅支持单个grpc服务端的设置&#xff0c;所以会有…