前缀和(下)

目录

热身:

寻找数组的中心下标

题解:

代码:

进阶:

除自身之外数组的乘积

题解:

代码: 

和为K的子数组

题解:

代码:

和可被 K 整除的子数组

题解:

同余定理:

为什么需要修正负数取模?

代码: 

连续数组

代码:

 


热身:

寻找数组的中心下标

724. 寻找数组的中心下标 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/find-pivot-index/description/

题解:

运用前缀和就可以解决这个问题,注意在本题中,中心下标的左侧数之和、右侧数之和均不包括中心下标的数。

我们定义前缀和、后缀和数组,根据题目要求,对前缀和数组的最左端、后缀和数组的最右端初始化为0。

代码:

class Solution {
public:int pivotIndex(vector<int>& nums) {int n=nums.size();vector<int> f(n);//前缀和vector<int> g(n);//后缀和f[0]=g[n-1]=0;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;}
};

进阶:

除自身之外数组的乘积

238. 除自身以外数组的乘积 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/product-of-array-except-self/description/

题解:

由于题目要求不用除法,所以我们不可以算出数组全部元素的乘积后再去除以 nums[ i ] 来得到答案。

在寻找数组的中心下标中,我们算出了 nums[ i ] 左侧和、右侧和,我们可以按照这个思路,算出 nums[ i ] 左侧乘积、右侧乘积,把左右两侧乘积相乘,就可以得到除自身之外数组的乘积。 

代码: 

class Solution {
public:vector<int> productExceptSelf(vector<int>& nums) {int n=nums.size();vector<int> f(n);//左侧乘积vector<int> g(n);//右侧乘积vector<int> ret(n);//返回值f[0]=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++){ret[i]=f[i]*g[i];}return ret;}
};

和为K的子数组

560. 和为 K 的子数组 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/subarray-sum-equals-k/description/

题解:

如下图,假设 k = 10,在给定的数组中,发现下标 2 ~ 5 的数组和 = k,而这一部分数组和,恰好为下标 0 ~ 5 的前缀和 - 下标 0  ~ 1 的前缀和(假设前缀和数组为 sum,则 K =  sum[ 5 ] - sum[ 1 ] ),所以我们可以用前缀和数组,快速得到和为 K 的子数组。

为了获得和为 K 的子数组的个数,我们可以在计算前缀和的同时,用哈希表记录每一个前缀和出现的次数。

比如 K =  sum[ 5 ] - sum[ 1 ] ,可以交换位置,变为 sum[ 5 ] - K = sum[ 1 ],由于记录了 sum[ 1 ] 出现的次数为 1 次,这样就可以得出当前和为 K 的子数组的个数为 1 个。

 由于我们用哈希表记录了每一个前缀和出现的个数,所以前缀和的计算可以不采用数组。

可能会出现以下情况:前缀和 sum - k == 0,但是哈希表中记录的前缀和并不存在 0,怎么处理?

 既然哈希表中不存在前缀和 0,那我们可以先放一个 0 进去,并把出现的次数设置为 1.

代码:

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

和可被 K 整除的子数组

974. 和可被 K 整除的子数组 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/subarray-sums-divisible-by-k/description/

题解:

同余定理:

假设 a % k == b % k ,则 ( a - b ) % k = 0.

举个例子,假设 k = 5,23 % 5 = 13 % 5,则(23 - 23 )% 5 = 0.

我们可以运用同余定理来解决这道题:

和上一题的思路相似,我们用 i 遍历数组,计算出下标 0 ~ i 的前缀和 sum,用哈希表记录 sum % K 出现的次数,如果 sum % K 曾经出现过,则存在和可被 K 整除的子数组,返回值 += 次数。

以示例 1 为例,假设返回值为 ret,比如下标 0 ~ 1 的前缀和取模后为 4,而下标 0 的前缀和取模后也为 4 ,而在此之前取模后为 4 出现的次数为 1,根据同余定理,子数组 [ 5 ] 可以被 K 整除,ret += 1,同理,下标 0 ~ 2 的前缀和取模后为 4,而在此之前取模后为 4 出现的次数为 2 ,所以此时 ret+=2 ,分别为 [ 5 ] , [ 5 , 0 ] , [ 0 ] ;下标 0 ~ 4 的前缀和取模后为 4,而在此之前取模后为 4 出现的次数为 3,所以此时 ret += 3 ,和可被 K 整除的子数组有 6 个,分别为  [ 5 ] , [ 5 , 0 ] , [ 0 ], [ 0, -2 , -3 ] , [ -2 , -3 ] ,[ 5 , 0, -2 , -3 ] ,以此类推。

注意 0 也可以被 K 整除!

为什么需要修正负数取模?

我们观察下面的例子:

存在子数组 [ 2, 3, 4 ] 的和可以被 3 整除,但是这在前缀和中无法体现出来。

再举个例子:

1、 7 % 3 = 1 , ( -2 ) % 3 = -2 ,但 [ 7 - ( -2 ) ] % 3 = 0 ;

2、( - 2) % 3 = -2 , ( -5 ) % 3 = -2 ,[ -2 - ( -5 ) ] % 3 = 0 。

可以看出当 a、b 同正同负时, a % k == b % k ,可以推出 ( a - b ) % k = 0,可以推出和可被 K 整除的子数组,但 a、b一正一负时,就没办法推出

为了让同余定理在一正一负的情况下也可以成立,我们可以对负数取模进行修正,把取模后的结果修改为正数,这样 a、b 就都是正数:

 int r=(sum%k+k)%k;

 再回到一开始举的例子,通过修正取模后,就可以得到正确的结果:

代码: 

class Solution {
public:int subarraysDivByK(vector<int>& nums, int k) {int sum=0,ret=0;unordered_map<int,int> hash;hash[0]=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];hash[r]++;}return ret;}
};

连续数组

525. 连续数组 - 力扣(LeetCode) 

 这道题用到的方法比较巧妙,利用了前缀和,

1、如果 nums[ i ] 为 0,则 sum += -1;

2、如果 nums[ i ] 为 1,则 sum += 1。

如果此时的前缀和 sum 在之前已经出现过了,假设上一次出现的下标为 j,说明 i 和 j 中间的这段数组的 0 和 1 的数量相等,只有相等了,才会相互抵消,前缀和才会再次变为 sum。

代码:

class Solution {
public:int findMaxLength(vector<int>& nums) {unordered_map<int,int> hash;hash[0]=-1;int ret=0;int sum=0;for(int i=0;i<nums.size();i++){sum+=(nums[i]==0?-1:1);if(hash.count(sum)) ret=max(ret,i-hash[sum]);else hash[sum]=i;}return ret;}
};

 

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

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

相关文章

Python多进程加快for循环速度

Python多进程加快for循环速度 你可以使用Python的multiprocessing模块来将for循环改为多进程实现。下面是一个简单的示例代码&#xff0c;演示了如何使用multiprocessing.Pool来并行执行一个for循环&#xff1a; import multiprocessing# 定义一个函数&#xff0c;该函数会在…

C语言 指针——指针变量做函数参数

目录 指针变量的解引用 为什么要用指针变量做函数参数&#xff1f; 演示Call by value 指针变量的解引用 为什么要用指针变量做函数参数&#xff1f; 演示Call by value

本特利330130-040-01-00 PLC模块深度解析 询价联系ID

本特利330130-040-01-00 PLC模块深度解析 在工业自动化领域&#xff0c;准确、高效的数据采集和监控是确保生产安全、提高生产效率的关键。本特利&#xff08;Bently Nevada&#xff09;作为全球知名的工业自动化和监控设备制造商&#xff0c;其生产的330130-040-01-00 PLC模块…

半藏酒业新零售分红制度拆解,起盘运营服务商

半藏酱酒招商模式&#xff0c;白酒合伙人模式&#xff0c;顶层模式设计 社群玩法用这几年的互联网词汇描述叫私域营销。虽然不走传统商超&#xff0c;酒桌之外很少能看到&#xff0c;但随着核心消费者裂变和流量汇聚&#xff0c;现在能见度越来越高&#xff0c;并溢出到达公域。…

Jtti:怎么在香港服务器上实现多点备份?

在香港服务器上实现多点备份可以采用多种方法和工具&#xff0c;主要目标是将数据备份到不同的存储位置&#xff0c;以增加数据的安全性和可靠性。以下是实现多点备份的一些常用方法&#xff1a; 1. 使用云存储服务 利用云存储服务将数据备份到不同的云存储提供商&#xff0c;以…

2024黑龙江CCPC

2024黑龙江省赛 B. String 思路:栈模拟代码&#xff1a; /* * Author: Hfuubigstrength * email: 2854614012qq.com * Date: 2024-05-28 23:32:45 */ #include <bits/stdc.h> //#define int long long #define PII pair<int,int> #define LL long long #defi…

深度学习:手撕 RNN(2)-RNN 的常见模型架构

本文首次发表于知乎&#xff0c;欢迎关注作者。 上一篇文章我们介绍了一个基本的 RNN 模块。有了 这个 RNN 模块后&#xff0c;就像搭积木一样&#xff0c;以 RNN 为基本单元&#xff0c;根据不同的任务或者需求&#xff0c;可以构建不同的模型架构。本节介绍的所有结构&#…

JS移动端设置mouseover,mouseleave有效么

在移动设备的浏览器环境中&#xff0c;mouseover 和 mouseleave 事件的行为与桌面浏览器有所不同&#xff0c;主要是因为移动设备的交互方式主要是基于触摸的&#xff0c;而不是基于鼠标的。 在移动设备上&#xff0c;当用户触摸屏幕时&#xff0c;通常会触发 touchstart 事件…

mysql查询的时间复杂度

SELECT * FROM customers WHERE age > 25; 首先是普通的select&#xff0c;如果没有建立任何的索引的话&#xff0c;假设数据量为N&#xff0c;那么时间复杂度为O(N) 如果对age添加了索引&#xff0c;那么复杂度为O(log n) 假设使用了in操作&#xff0c;总共查找M种&…

Codeforces Round 947 (Div. 1 + Div. 2) D. Paint the Tree 题解 DFS

Paint the Tree 题目描述 378QAQ has a tree with n n n vertices. Initially, all vertices are white. There are two chess pieces called P A P_A PA​ and P B P_B PB​ on the tree. P A P_A PA​ and P B P_B PB​ are initially located on vertices a a a an…

Spring Boot与MongoDB集成指南

1. 引言 在当今快速发展的软件开发领域&#xff0c;选择合适的技术栈对于构建高效、可扩展的应用程序至关重要。随着微服务架构和云原生应用的兴起&#xff0c;开发人员需要更灵活、更快速的解决方案来满足不断变化的业务需求。Spring Boot和MongoDB的结合正是这一需求的完美答…

运维开发.MySQL.范式与反范式化

运维开发 MySQL.三大范式 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28550263/artic…

jest测试

文章目录 测试testexpecttoThrow asyncPromiseAsync/Await 作用域一次性设置 beforeAll and afterAll重复设置 beforeEach 和 afterEachdescribe 块 mockcli配置覆盖率测试报告 测试 test test(name, () > {function} }expect () > {expect(期望value).toBe(匹配value…

python海龟绘图(你的作业说不定就在这里)

三角形 from turtle import * for i in range(3):forward(100)left(120)基本绘图​​​​​ 让海龟前进 100 步: forward(100)你应该会看到&#xff08;最可能的情况&#xff0c;是在你的显示器的一个新窗口中&#xff09;海龟画出一条线段&#xff0c;方向朝东。 改变海龟的…

spdlog日志库源码:线程池thread_pool

线程池 线程池本质上一组事先创建的子线程&#xff0c;用于并发完成特定任务的机制&#xff0c;避免运行过程中频繁创建、销毁线程&#xff0c;从而降低程序运行效率。通常&#xff0c;线程池主要涉及到以下几个方面问题&#xff1a; 如何创建线程池&#xff1f;线程池如何执…

Ubuntu22.04之解决:登录计算机的密码与登录密钥环里的密码不再匹配(二百三十四)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

微信网页版登录插件v1.1.1

说到如今的微信客户端&#xff0c;大家肯定会有很多提不完的意见或者建议。比如这几年体积越来越大&#xff0c;如果使用频率比较高&#xff0c;那占用空间就更离谱了。系统迷见过很多人电脑C盘空间爆满&#xff0c;都是由于微信PC版造成的。 而且&#xff0c;它还加了很多乱七…

15、Spring系统-AOP

ProxyFactory选择cglib或jdk动态代理原理 ProxyFactory在生成代理对象之前需要决定到底是使用JDK动态代理还是CGLIB技术&#xff1a; 代理对象创建过程 JdkDynamicAopProxy 在构造JdkDynamicAopProxy对象时&#xff0c;会先拿到被代理对象自己所实现的接口&#xff0c;并且…

VSCODE终端输出中文乱码 菱形问号?

问题现象 VSCODE终端输出中文乱码 菱形问号&#xff1f; 解决方法 方法一 设置系统环境变量 变量名&#xff1a;PYTHONIOENCODING 值&#xff1a;utf8 方法二 安装插件Code Runner插件在设置中搜索 code-runner.executorMap&#xff0c;再点击在setting.json中编辑&#x…

达梦数据库

达梦数据库 达梦Docker部署 达梦Docker部署 1、下载链接 https://pan.baidu.com/s/1RI3Lg0ppRhCgUsThjWV6zQ?pwdjc62 2、docker启动命令 docker run -d -p 5236:5236 \ --restartalways \ --name dm8 \ -e LD_LIBRARY_PATH/app/dm8/bin \ -e LENGTH_IN_CHAR1 \ -e CASE_SENS…