专题四:前缀和

news2025/2/24 14:28:22

前缀和

  • 一.一维前缀和(模板):
    • 1.思路一:暴力解法
    • 2.思路二:前缀和思路
  • 二. 二维前缀和(模板):
    • 1.思路一:构造前缀和数组
  • 三.寻找数组的中心下标:
    • 1.思路一:前缀和
  • 四.除自身以外数组的乘积:
    • 1.思路一:暴力解法
    • 2.思路二:前缀积+后缀积
  • 五.和为K的子数组:
    • 1.思路一:前缀和+哈希
  • 六.前缀和可以被K整除的子数组:
    • 1.思路一:前缀和+哈希
  • 七.连续数组:
    • 1.思路一:
  • 八.矩阵区域和:
    • 1.思路一:二维前缀和模板+细节处理

一.一维前缀和(模板):

请添加图片描述
一维前缀和

1.思路一:暴力解法

1.输入数组长度n和查询次数q。
2.使用一个一维数组保存数据。
3.使用一个循环获取q次需要查询范围的数据。
4.遍历r-l+1次进行一个范围求和然后输出。
5.时间复杂度:O(n^2)
6.通过不了所有的测试用例。

2.思路二:前缀和思路

1.输入数组长度n和查询次数q。
2.使用一个一维数组保存数据。
3.构建一个前缀和的一个数组。
在这里插入图片描述
4.使用一个循环获取q次需要查询范围的数据。
5.时间复杂度:O(n^2)
6.通过不了所有的测试用例。

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    //1.输入数组长度和查询次数: 
    int n =0,q=0;
    cin>>n>>q;
    //2.输入数组数据:
    vector<int> arr(n+1);
    for(int i=1;i<=n;i++) cin>>arr[i];
    //3.前缀和数组:
    vector<long long> bp(n+1);
    for(int i=1;i<=n;i++) bp[i] = bp[i-1] + arr[i];
    //4.计算和:
    int i=0,r=0;
    while(q!=0)
    {
        cin>>i>>r;
        cout<<(bp[r] - bp[i-1])<<endl;
        q--;
    }
}

二. 二维前缀和(模板):

请添加图片描述
二维前缀和

1.思路一:构造前缀和数组

在这里插入图片描述

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    //1.n行m列的一个二维数组:
    int n = 0, m = 0, q = 0;
    cin >> n >> m >> q;
    //2.数组输入数据:
    vector<vector<int>> vv((n + 1),vector<int>(m+1));
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)cin >> vv[i][j];
    }

    //3.创造二维的求和dp数组
    vector<vector<long long>> dp((n + 1), vector<long long>(m + 1));
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            dp[i][j] = ((dp[i][j - 1] + dp[i - 1][j]) - dp[i-1][j-1]) + vv[i][j];
        }
    }
    //4.数据查询:

    while (q != 0)
    {
        int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
        cin >> x1 >> y1 >> x2 >> y2;

        cout << (dp[x2][y2] - (dp[x1 - 1][y2] + dp[x2][y1-1]) + dp[x1-1][y1-1]) << endl;
        q--;
    }


}

三.寻找数组的中心下标:

在这里插入图片描述

寻找数组的中心下标

1.思路一:前缀和

在这里插入图片描述

class Solution {
public:
    int pivotIndex(vector<int>& nums) {
        
        //1.构建前缀和数组:
        int n = nums.size();
        vector<int> dp(n+1);
        //2.前缀和数组值遍历:
        for(int i = 1 ; i<=n;i++) dp[i] = dp[i-1] + nums[i-1];

        //3.进行中心下标的寻找:
        int mid = -1;
        for(int i=1 ; i <= n ; i++)
        {
            if((dp[i-1] - dp[0]) == (dp[n] - dp[i]))
            {
                mid = i-1;
                break;
            }
        }
        //4.没有中心下标的情况:
        return (mid == -1? -1:mid);
    }
};

四.除自身以外数组的乘积:

在这里插入图片描述

除自身以外数组的乘积

1.思路一:暴力解法

在这里插入图片描述

2.思路二:前缀积+后缀积

在这里插入图片描述

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {

        //1.前缀积+后缀积
        int n = nums.size();
        vector<int> left(n + 1, 1);
        vector<int> right(n + 1, 1);

        //2.遍历确定前缀积+后缀积的值:
        for (int i = 1; i <= n; i++) left[i] = left[i - 1] * nums[i - 1];
        for (int i = n - 1; i >= 0; i--) right[i] = right[i + 1] * nums[i];

        // 1  1  2  6  24
        // 24 24 12 4  1
        // 0  1  2  3  4

        //0   1   2  3
        //24  12  8  6
        vector<int> ret(n);
        //3.遍历ret数组并且赋值
        for (int i = 0; i < n; i++)
        {
            ret[i] = left[i] * right[i+1];
        }

        return ret;
    }
};

五.和为K的子数组:

在这里插入图片描述

和为K的子数组

1.思路一:前缀和+哈希

在这里插入图片描述

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

六.前缀和可以被K整除的子数组:

在这里插入图片描述

前缀和可以被K整除的子数组

1.思路一:前缀和+哈希

在这里插入图片描述

class Solution {
public:
    int subarraysDivByK(vector<int>& nums, int k) {
        unordered_map<int,int> hash;
        hash[0] = 1;

        //1.开始遍历+判断
        int sum = 0 , ret = 0;
        for(auto a : nums)
        {
            sum+=a;
            int n = (sum%k + k) % k;

            if(hash.count(n)) ret+=hash[n];
            hash[n]++;
        }
        return ret;
    }
};

七.连续数组:

请添加图片描述

连续数组

1.思路一:

在这里插入图片描述

在这里插入图片描述

class Solution {
public:
    int findMaxLength(vector<int>& nums) {
        vector<int> nums_1(nums);
        for(auto& n:nums_1)
        {
            if(n==0) n = -1;
        }

        //2.hash+前缀和的思路
        unordered_map<int,int> hash;
        //1.前缀和为0的下标处理:
        hash[0] = -1;
        int sum = 0,ret = 0;
        for(int i=0;i<nums.size();i++)
        {
            sum+=nums_1[i];
            if(hash.count(sum)) ret = max(ret , i - hash[sum]);
            else hash[sum] = i;
        }
        return ret;
    }
};

八.矩阵区域和:

请添加图片描述

矩阵区域和

1.思路一:二维前缀和模板+细节处理

在这里插入图片描述

class Solution {
public:
    vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) {
        int m = mat.size();
        int n = mat[0].size();

        //1.创建(m+1) * (n+1) 大小的二维数组
        vector<vector<int>> dp(m+1 , vector<int>(n+1));

        //2.dp数组赋值:
        for(int i=1 ; i<=m ; i++)
        {
            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];
            }
        }

        //3.使用dp数组并且考虑i-k 和 j-k的越界问题:
        vector<vector<int>> ret(m,vector<int>(n));

        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/1340902.html

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

相关文章

java设计模式学习之【备忘录模式】

文章目录 引言备忘录模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用备忘录示例代码地址 引言 想象一下&#xff0c;你正在编辑一篇重要的文档&#xff0c;突然你意识到最近的一些更改实际上破坏了文档的结构。幸运的是&#xff0c;你的文本编辑器允许你撤…

Java的maven

一.概念&#xff1a; 是一款用于管理和构建java项目的工具 作用: 方便项目的依赖管理 统一项目的结构,方便程序员开发及维护 提供了一套标准的项目构建流程,方便编译和构建 二.仓库类型: 本地仓库>自己计算机上的一个目录 中央仓库>由Maven团队维护的全球唯一的。…

两个小妙招,给win to go添加PE,Windows去除快捷方式小箭头

两个小妙招&#xff0c;给win to go添加PE&#xff0c;Windows去除快捷方式小箭头。 一个超级简单的给wintogo添加PE的方法。我的wintogo是UEFIMBR,VHDX&#xff08;此方法同样适合于传统模式&#xff09; 第一步&#xff0c;找到一个把维护工具集成在wim里的pe&#xff0c;这…

C#集合类型总结和性能分析

C#集合类型总结和性能分析 文章引用C#集合类型概述各集合类底层接口关系图泛型与非泛型集合分析具体接口/类分析CollectionBase/DictionaryBase的目的IEnumerator/IEnumerable/IEnumerable<T>ICollection<T>和ICollectionIList和IListIReadOnlyList<T>IDicti…

腾讯云服务器怎么买划算?腾讯云服务器新用户优惠购买攻略

腾讯云轻量应用服务器购买指南&#xff0c;有两个入口&#xff0c;一个是在特价活动上购买&#xff0c;一个是在轻量应用服务器官方页面购买&#xff0c;特价活动上购买价格更便宜&#xff0c;轻量2核2G3M带宽服务器62元一年起&#xff0c;阿腾云atengyun.com分享腾讯云轻量应用…

Python入门知识点分享——(十一)if条件语句

if条件语句是一种编程语言中用于控制程序流程的结构。它根据一个条件的真假来决定执行不同的代码块。 if条件语句通常由if关键字、一个条件表达式和一个代码块组成。条件表达式可以是一个返回布尔值的表达式&#xff0c;如果条件为真&#xff0c;则执行代码块中的代码&#xf…

《MySQL》事务篇

事务特性 ACID Atomicity原子性&#xff1a;事务中的操作要么全部完成&#xff0c;要么全部失败。 Consistency一致性&#xff1a;事务操作前后&#xff0c;数据满足完整性约束。 Isolation隔离性&#xff1a;允许并发执行事务&#xff0c;每个事务都有自己的数据空间&…

【算法刷题】Day26

文章目录 1. 买卖股票的最佳时机含冷冻期题干&#xff1a;算法原理&#xff1a;1. 状态表示&#xff1a;2. 状态转移方程3. 初始化4. 填表顺序5. 返回值 代码&#xff1a; 2. 替换所有的问号题干&#xff1a;算法原理&#xff1a;代码&#xff1a; 1. 买卖股票的最佳时机含冷冻…

web3方向产品调研

每次互联网形态的改变&#xff0c;都会对世界产生很大的影响&#xff0c;上一次对社会产生重大影响的互联网形态&#xff08;Web2.0&#xff09;催生了一批改变人类生活和信息交互方式的企业。 目录 概述DAO是什么&#xff1f;为什么我们需要DAO? 金融服务金融桥接及周边服务D…

在uniapp中使用背景渐变色与背景图不生效问题

list上有文字详情以及背景图&#xff0c;从背景可以看出是渐变色和 背景图片的结合。 因为使用到渐变色&#xff0c;所以要结合 background-blend-mode 属性来实现与背景图片叠加显示&#xff0c;否则只通过 background: linear-gradient(); background-image: url(); 设置不会…

申请sectigo和certum的IP证书注意事项

IP数字证书可以为只有公网IP地址的站点提供网站传输信息加密服务&#xff0c;一方面可以消除用户在浏览器访问网站时的“不安全”提示&#xff0c;另一方面现在主流浏览器会优先收录安装了数字证书的网站&#xff0c;为公网IP地址网站安装IP证书有利于提升网站SEO&#xff08;搜…

openGauss学习笔记-175 openGauss 数据库运维-备份与恢复-导入数据-管理并发写入操作示例

文章目录 openGauss学习笔记-175 openGauss 数据库运维-备份与恢复-导入数据-管理并发写入操作示例175.1 相同表的INSERT和DELETE并发175.2 相同表的并发INSERT175.3 相同表的并发UPDATE175.4 数据导入和查询的并发 openGauss学习笔记-175 openGauss 数据库运维-备份与恢复-导入…

oracle下载

前言&#xff1a; 官网上提供都是最新的什么19c 21c这些版本&#xff0c;我要的是 11g 12c 或者更老的 8i 9i 这些版本。 准备下载一个oracle12c 版本&#xff0c;但是找了很久&#xff0c;最终…详情请看下面 oracle 数据库版本介绍 Oracle数据库有多个长期支持版本&#x…

万字长文谈自动驾驶bev感知(一)

文章目录 prologuepaper listcamera bev :1. Lift, Splat, Shoot: Encoding Images from Arbitrary Camera Rigs by Implicitly Unprojecting to 3D2. M2BEV: Multi-Camera Joint 3D Detection and Segmentation with Unified Birds-Eye View Representation3. BEVDet: High-Pe…

Android原生实现单选

六年前写的一个控件&#xff0c;一直没有时间总结&#xff0c;趁年底不怎么忙&#xff0c;整理一下之前写过的组件。供大家一起参考学习。废话不多说&#xff0c;先上图。 一、效果图 实现思路使用的是radioGroup加radiobutton组合方式。原理就是通过修改RadioButton 的backgr…

Python遥感影像深度学习指南(5)-使用GEE为图像分割创建训练图像patchs

在遥感影像图像分割训练过程中,有些情况下,我们需要从一开始就准备自己的数据集,而如果没有合适的工具,这可能会很耗时。 1、在GEE中选择影像 首先,我们需要一个 GEE 平台的免费账户,可以在 https://signup.earthengine.google.com/ 上轻松获得。然后,我们将进入代码编…

技术资讯:2023编程语言排行榜,出炉啦!

大家好&#xff0c;我是大澈&#xff01; 本文约2000字&#xff0c;整篇阅读大约需要4分钟。 感谢关注微信公众号&#xff1a;“程序员大澈”&#xff0c;免费领取"面试礼包"一份&#xff0c;然后免费加入问答群&#xff0c;从此让解决问题的你不再孤单&#xff01…

C# Winform教程(一):MD5加密

1、介绍 在C#中&#xff0c;MD5&#xff08;Message Digest Algorithm 5&#xff09;是一种常用的哈希函数&#xff0c;用于将任意长度的数据转换为固定长度的哈希值&#xff08;通常是128位&#xff09;。MD5广泛用于校验数据完整性、密码存储等领域。 2、示例 创建MD5加密…

安卓无法下载gradle或者下载gradle只有几十k的时候怎么办

简单说明&#xff1a;检查项目根目录的build.gradle文件&#xff0c;新版本的检查setting.gradle文件&#xff0c;看看repositories中有没有mavenCentral()&#xff0c;没有的话&#xff0c;加上&#xff0c;放在前面&#xff0c;把阿里的镜像也放上maven { url ‘https://mave…

laravel5.8中实现验证码组件的安装和验证

本篇文章主要讲解使用laravel5.8自带的验证码库实现验证码验证的效果教程。通过本教程你可以快速接入到自己的项目中开发相应的验证功能。 作者&#xff1a;任聪聪 (rccblogs.com) 日期&#xff1a;2023年12月17日 实际效果 安装步骤 步骤一、输入命令 composer require mews…