前缀和篇——繁星斗斗数字交织中,觅得效率明月辉光(3)

news2025/3/1 23:06:59

在这里插入图片描述

前言

本篇带来前缀和的最终部分,与之前相同,将结合难度进一步提升的题目进行详细分析讲解,以深化对该算法的理解运用。

一. 和可被k整除的子数组

1.1 题目链接:https://leetcode.cn/problems/subarray-sums-divisible-by-k/description/

1.2 题目分析:

该题与上篇和为K的子数组要求类似,只是此处要求和可被K整除。

1.3 思路讲解

在此之前,我们先补充一下本题需要使用的数学知识:同余定理。

如果 (a - b) % n == 0 ,那么我们可以得到⼀个结论: a % n == b % n 。***⽤⽂字叙
述就是,如果两个数相减的差能被 n 整除,那么这两个数对 n 取模的结果相同。

例如: (26 - 2) % 12 == 0 ,那么 26 % 12 == 2 % 12 == 2 。

余数修正

c++ 中负数取模的结果,以及如何修正「负数取模」的结果:

a. c++ 中关于负数的取模运算,结果是「把负数当成正数,取模之后的结果加上⼀个负号」。 例如: -1 % 3 = -(1 % 3) =-1
b. 因为有负数,为了防⽌发⽣「出现负数」的结果,以 (a % n + n) % n 的形式输出保证为 正。 例如: -1 % 3 = (-1 % 3 + 3) % 3 = 2

暴力解法(会超时):
与之前相同,逐个遍历枚举。

前缀和:

  • . 首先,我们用sum[i]表示下标为i的元素的前缀和。
    如图,和可被K整除的子数组,即代表[x,i]内的元素和sum[i]-sum[x]可被k整除
    在这里插入图片描述
  • 由同余定理可得,(sum[i]-sum[x])%k==0,可得出sum[i]%k与sum[x]%k相等。
  • 因此问题就转化为,求有多少个前缀和可被k整除的数组,即找到在 [0, i - 1] 区间内,有多少前缀和的余数等于 sum[i] % k 的即可。
  • 同时由于负数取模的性质,在取模时需要对余数进行修正。

1.4 代码实现:

class Solution {
public:
    int subarraysDivByK(vector<int>& nums, int k) {
        unordered_map<int,int> hash;//记录前缀和及出现次数
        int sum=0,ret=0;
        hash[0%k]=1;
        for(int i=0;i<nums.size();i++)
        {
            sum+=nums[i];
            int r=(sum%k+k)%k;//修正余数
            if(hash.count(r))
            {
                ret+=hash[r];
            }//说明此时该子数组可被k整除
            hash[r]++;
        }
        
        return ret;
    }
};

二. 连续数组

2.1 题目链接:https://leetcode.cn/problems/contiguous-array/description/

2.2 题目分析:

题目要求找出最长的连续子数组,且该子数组内0和1的个数相等

2.3 思路讲解:

暴力解法(会超时):
枚举所有的子数组,判断是否满足条件。

前缀和:
题目的关键之处在于,所求的最长子数组内0和1的个数相等,暴力算法内的时间冗余也主要在判断是否相等上。
不妨将题目内的0变为-1,那么此时符合条件的子数组所有元素和则必然为0,大大简化了判断条件。

具体步骤如下:

  • 采用哈希表记录前缀和及其出现的位置,sum来记录当前的和,ret记录返回的数组长度
  • 当元素为0时,sum-1,当元素为1时,sum+1
  • 当满足条件时,更新ret,否则则更新哈希表

2.4 代码实现:

class Solution {
public:
    int findMaxLength(vector<int>& nums) {
        unordered_map<int,int> hash;//记录前缀和及出现的位置
        
        int sum=0,ret=0;
        hash[0]=-1;//记录起始位置,防止最大子数组为数组本身的情况
        for(int i=0;i<nums.size();i++)
        {
            sum+=nums[i]==0?-1:1;
            if(hash.count(sum))
            {
                ret=max(ret,i-hash[sum]);
            }//更新ret
            else
            {
                hash[sum]=i;
            }

        }
        return ret;
        
    }
};

三. 矩阵区域和

3.1 题目链接:https://leetcode.cn/problems/matrix-block-sum/description/

3.2 题目分析:

本题看内容介绍较为抽象,可以把K理解为行列的扩充数,如题中所给示例:
1 2 3
4 5 6
7 8 9
此时k=1,因此answer[0][0]即为在原矩阵mat[0][0]的基础上行列各扩张一行,此时区域内的元素就包括mat[0][0],mat[0][1],mat[1][0],mat[1][1],因此和为1+2+4+5等于12.
注意:在扩充时如果超出矩阵本身界限,则超出部分不予处理。

3.3 思路讲解:

在第一篇中,我们详细讲解了二维矩阵的前缀和计算方法,因此在此处不再加以赘述,着装讲解本题思路。
具体步骤如下:

  • 首先,由于本题要处理边界问题,我们首先求出行m和列n,并构建前缀和矩阵
  • 在进行扩充时,注意矩阵区域和的左右边界均不可超出矩阵本身
  • 前缀和矩阵dp[i][j]的求法在第一篇中有详细说明,如果存在遗忘可移步进行查看。

第一篇链接:https://blog.csdn.net/2303_81060385/article/details/144199070?spm=1001.2014.3001.5502

3.4 代码实现:

class Solution {
public:
    vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) {
        int m=mat.size(),n=mat[0].size();
        vector<vector<int>> dp(m+1,vector<int>(n+1));//构建前缀和矩阵
        vector<vector<int>> ret(m,vector<int>(n));//返回矩阵
        //处理前缀和数组
        for(int i=1;i<m+1;i++)
        {
            for(int j=1;j<n+1;j++)
            {
                dp[i][j]=dp[i-1][j]+dp[i][j-1]+mat[i-1][j-1]-dp[i-1][j-1];
            }
        }
        //使用前缀和数组
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
               int x1=max(0,i-k)+1,y1=max(0,j-k)+1;//确定左上边界
               int x2=min(m-1,i+k)+1,y2=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.coloradmin.cn/o/2257535.html

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

相关文章

【 C++ 入门基础】 —— 双壁传奇C语言和C++的爱恨情仇

C学习笔记&#xff1a; C 进阶之路__Zwy的博客-CSDN博客 各位于晏&#xff0c;亦菲们&#xff0c;请点赞关注&#xff01; 我的个人主页&#xff1a; _Zwy-CSDN博客 目录 1、从C语言到C的进化 1.1、历史渊源 1.2、语法层面的区别和联系 1.2.1、数据类型 1.2.2、函数定…

013路由协议-OSPF

OSPF具有更适用于规模较大的网络环境&#xff0c;收敛更快速、依据带宽来计算路径成本等。 计算方式&#xff1a; 100M/当前端口的带宽 如果小于1就按照1来计算 例如&#xff1a; 当前端口的带宽是1.54M 路径成本 100/1.54 65 当前端口的带宽是 1000M 路径成本 100/100 0.…

最新版Chrome谷歌加载ActiveX控件之金格iWebPDF2018控件

背景 金格iWebPDF2018控件是一款方便用户在线打开PDF文档的控件。 allWebPlugin中间件是一款为用户提供安全、可靠、便捷的浏览器插件服务的中间件产品&#xff0c;致力于将浏览器插件重新应用到所有浏览器。它不仅可以实现ActiveX控件在现代浏览器上使用&#xff0c;而且集成也…

没有在 SCM 配置或者插件中的 Git 存储库配置错误

问题&#xff1a; jenkins 配置新项目后首次运行报错如下&#xff0c;同时git代码分支无法选择。 已返回默认值 没有在 SCM 配置或者插件中的 Git 存储库配置错误 选项"使用仓库"设置为:"http://xxxx.git 请检查配置 原因&#xff1a; 配置pipeline 脚本时指…

AI时代的开发新纪元:云开发 Copilot

AI时代的开发新纪元&#xff1a;云开发 Copilot 目录 引言&#xff1a;AI时代的开发新纪元低代码与AI的完美融合云开发 Copilot的革命性意义云开发 Copilot 的核心特性解析 快速生成应用功能低代码与AI的深度结合 实战演练&#xff1a;云开发 Copilot 的应用案例 从需求到实现…

微信小程序粘贴剪切板内容

wx.getClipboardData(Object object) 获取系统剪贴板的内容 wx.getClipboardData({success: function (res) {if (res.data) {// 获取成功...} else {wx.showToast({title: "没有粘贴内容",icon: "error",});}},fail: function (res) {wx.showToast({titl…

【PyQt5教程 四】Qt Designer 样式表(styleSheet)实现基本小部件的自定义动态效果和资源浏览器背景添加方法

目录 一、成果演示&#xff1a; 二、样式表的使用方法: &#xff08;1&#xff09;样式表语法和属性&#xff1a; &#xff08;2&#xff09;样式表代码示例&#xff1a; &#xff08;3&#xff09;伪类和状态&#xff1a; &#xff08;4&#xff09;复合选择器&#xff…

推荐系统里面的多任务学习概述

1. 概述 多任务学习&#xff08;multi-task learning&#xff09;&#xff0c;本质上是希望使用一个模型完成多个任务的建模&#xff0c;在推荐系统中&#xff0c;多任务学习一般即指多目标学习&#xff08;multi-label learning&#xff09;&#xff0c;不同目标输入相同的fe…

基于Springboot技术的实验室管理系统【附源码】

基于Springboot技术的实验室管理系统 效果如下&#xff1a; 系统登录页面 实验室信息页面 维修记录页面 轮播图管理页面 公告信息管理页面 知识库页面 实验课程页面 实验室预约页面 研究背景 在科研、教育等领域&#xff0c;实验室是进行实验教学和科学研究的重要场所。随着…

Abaqus断层扫描三维重建插件CT2Model 3D V1.1版本更新

更新说明 Abaqus AbyssFish CT2Model3D V1.1版本更新新增对TIF、TIFF图像文件格式的支持。本插件用户可免费获取升级服务。 插件介绍 插件说明&#xff1a; Abaqus基于CT断层扫描的三维重建插件CT2Model 3D 应用案例&#xff1a; ABAQUS基于CT断层扫描的细观混凝土三维重建…

【开源】A066—基于JavaWeb的农产品直卖平台的设计与实现

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看项目链接获取⬇️&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600个选题ex…

ChatGPT Pro是什么

ChatGPT Pro 和 ChatGPT Plus 的区别主要体现在功能范围、适用场景和目标用户上。 ChatGPT Plus 功能 • 价格&#xff1a;20美元/月。 • 目标用户&#xff1a;针对个人用户设计。 • 主要特点&#xff1a; • 在高峰期响应速度更快。 • 使用高级模型&#xff08;如 GPT-4…

增加数据长度——提高频率分辨率

由于运算方式和存储容量的限制&#xff0c;计算机只能处理离散且有限长的数据&#xff0c;故“不得不”将无限长的采样序列在时域截断&#xff0c;再进行后续处理。由数据在时域截断引起失真。 分析余弦序列 x ( n ) cos ⁡ ( ω 0 n ) x(n) \cos(\omega_0 n) x(n)cos(ω0​…

天喻InteKEY加密软件卸载

1 概述 有些小伙伴向我求助&#xff0c;说他们的电脑上被迫安装了天喻InteKEY加密软件&#xff0c;现在所有的office文档、代码等文件都会自动加密&#xff0c;传给别人&#xff0c;都是乱码&#xff0c;无法打开。 如下图所示&#xff1a; 请求我能不能帮他们把这些加密的文…

【报错】新建springboot项目时缺少resource

1.问题描述 在新建springboot项目时缺少resources,刚刚新建时的目录刚好就是去掉涂鸦的resources后的目录 2.解决方法 步骤如下&#xff1a;【文件】--【项目结构】--【模块】--【源】--在main文件夹右击选择新建文件夹并命名为resources--在test文件夹右击选择新建文件夹并命名…

【PlantUML系列】流程图(四)

目录 目录 一、基础用法 1.1 开始和结束 1.2 操作步骤 1.3 条件判断 1.4 并行处理 1.5 循环 1.6 分区 1.7 泳道 一、基础用法 1.1 开始和结束 开始一般使用start关键字&#xff1b;结束一般使用stop/end关键字。基础用法包括&#xff1a; start ... stopstart ...…

计算机网络:传输层、应用层、网络安全、视频/音频/无线网络、下一代因特网

目录 &#xff08;五&#xff09;传输层 1&#xff0e;传输层寻址与端口 2&#xff0e;无连接服务与面向连接服务 3. 传输连接的建立与释放 4. UDP 的优点 5. UDP 和 TCP 报文段报头格式 6. TCP 的流量控制 7&#xff0e;TCP 的拥塞控制 8. TCP 传送连接的管理 &#…

【cpp/c++ summary 语法总结】细节(作为参数时) 数组退化

在C语言中&#xff0c;参数传递通常是通过值传递&#xff08;pass by value&#xff09;的方式进行的&#xff0c;这意味着当调用函数时&#xff0c;实际参数的值会被复制到对应的形参中。因此&#xff0c;函数内部操作的是这些值的副本&#xff0c;而不是原始变量本身。这种方…

Python生成对抗神经网络GAN预测股票及LSTMs、ARIMA对比分析ETF金融时间序列可视化

全文链接&#xff1a;https://tecdat.cn/?p38528 本文聚焦于利用生成对抗网络&#xff08;GANs&#xff09;进行金融时间序列的概率预测。介绍了一种新颖的基于经济学驱动的生成器损失函数&#xff0c;使 GANs 更适用于分类任务并置于监督学习环境中&#xff0c;能给出价格回…

常用环境部署(二十四)——Docker部署开源物联网平台Thingsboard

1、Docker和Docker-compose安装 参考网址如下&#xff1a; CENTOS8.0安装DOCKER&DOCKER-COMPOSE以及常见报错解决_centos8安装docker-compose-CSDN博客 2、 Thingsboard安装 &#xff08;1&#xff09;在/home目录下创建docker-compose.yml文件 vim /home/docker-com…