算法专题四:前缀和

news2024/12/23 11:08:29

前缀和

  • 一.一维前缀和(模板):
    • 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/1343881.html

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

相关文章

002文章解读与程序——中国电机工程学报EI\CSCD\北大核心《计及源荷不确定性的综合能源生产单元运行调度与容量配置两阶段随机优化》已提供下载资源

&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;下载资源链接&#x1f4…

nacos入门篇001-安装与启动

1、下载zip包 我这里下载的是版本2.2.0 Nacos 快速开始 2、修改配置文件 2.1集群模式修改成单例模式 vi startup.sh 2.2 修改数据库配置信息 3、初始化数据库 3.1 创建db名称&#xff1a;db_nacos 3.2 执行mysql-schema.sql 3.3 执行完截图&#xff1a; 4、运行脚本启动 …

leetcode贪心算法题总结(二)

本节目录 1.最长回文串2.增减字符串匹配3.分发饼干4.最优除法5.跳跃游戏II6.跳跃游戏7.加油站8.单调递增的数字9.坏了的计算器 1.最长回文串 最长回文串 class Solution { public:int longestPalindrome(string s) {//计数一&#xff1a;用数组模拟哈希表int hash[127] {0}…

SimpleCG小游戏开发系列(2)--贪吃蛇

一、前言 在之前的C语言小游戏开发系列我们已经介绍了扫雷游戏的开发&#xff0c;本篇我们继续此系列第二篇&#xff0c;同样是比较简单但好玩的一个游戏--贪吃蛇。因为有了之前的游戏框架&#xff0c;我们只需要直接搬来原来的框架即可&#xff0c;可以省去不少活。 先看看游…

命令行创建Vue项目

Vue项目创建 1. 打开UI界面 在命令行中&#xff0c;执行如下指令&#xff1a; vue ui 2. 打开项目管理器 3. 创建项目 创建项目的过程&#xff0c;需要联网进行&#xff0c;这可能会耗时比较长的时间&#xff0c;请耐心等待。 windows的命令行&#xff0c;容易卡顿&#xff0c…

使用Node Exporter采集主机数据

安装 Node Exporter 在 Prometheus 的架构设计中&#xff0c;Prometheus Server 并不直接服务监控特定的目标&#xff0c;其主要任务负责数据的收集&#xff0c;存储并且对外提供数据查询支持。因此为了能够能够监控到某些东西&#xff0c;如主机的 CPU 使用率&#xff0c;我们…

3D 渲染如何帮助电商促进销售?

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 3D 渲染图像因其高转化率而成为亚马逊卖家的最新趋势。它是电子商务平…

Linux 线程安全 (1)

文章目录 线程互斥概念互斥实际使用互斥锁的原理死锁问题说明 线程互斥概念 执行流 执行流是指操作系统对进程或线程的调度和执行顺序。它决定了程序中的指令按照何种顺序被执行。 现阶段可以粗浅的理解为&#xff0c;执行流决定执行哪个线程或进程的代码(或者说执行流决定了…

MyBatis标签及其应用示例

MyBatis标签及其应用示例 1. select 1.1 标签属性 id唯一的标识符parameterType传给此语句的参数的全路径名或别名如&#xff1a;com.xxx.xxx.demo.entity.User或userresultType语句返回值类型或别名。如果是集合List&#xff0c;此处填写集合的泛型T&#xff0c;而不是集合…

人机交互中信息数量与质量

在人机交互中&#xff0c;信息的数量和质量都是非常重要的因素。 信息的数量指的是交互过程中传递的信息的多少。信息的数量直接影响到交互的效率和效果&#xff0c;如果交互中传递的信息量太少&#xff0c;可能导致交互过程中的信息不足&#xff0c;用户无法得到想要的结果或者…

js实时监听input输入框值的变化

实习日记之通过调用common chemistry的api接口实现输入keyword查找cas号和mw。做了一个简单的html网页&#xff0c;用到了ajax技术。比较简单&#xff0c;适合刚入门的宝学习参考。代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head>&l…

面试算法78:合并排序链表

题目 输入k个排序的链表&#xff0c;请将它们合并成一个排序的链表。 分析&#xff1a;利用最小堆选取值最小的节点 用k个指针分别指向这k个链表的头节点&#xff0c;每次从这k个节点中选取值最小的节点。然后将指向值最小的节点的指针向后移动一步&#xff0c;再比较k个指…

cleanmymac这个软件怎么样?值不值得下载

cleanmymac是我必装的mac端清理软件&#xff0c;界面简洁好看&#xff0c;完美适配mac系统&#xff0c;文件清理的速度、精度都比较优秀&#xff0c;还是比较不错的呢。cleanmymac作为一款第三方清洁应用程序&#xff0c;具有专业完整的清理功能&#xff0c;包括释放内存、一键…

Halcon阈值处理的几种分割方法threshold/auto_threshold/binary_threshold/dyn_threshold

Halcon阈值处理的几种分割方法 文章目录 Halcon阈值处理的几种分割方法1. 全局阈值2. 基于直方图的自动阈值分割方法3. 自动全局阈值分割方法4. 局部阈值分割方法5. var_threshold算子6 . char_threshold 算子7. dual_threshold算子 在场景中选择物体或特征是图像测量或识别的重…

FairyGUI-Cocos Creator官方Demo源码解读

博主在学习Cocos Creator的时候&#xff0c;发现了一款免费的UI编辑器FairyGUI。这款编辑器的能力十分强大&#xff0c;但是网上的学习资源比较少&#xff0c;坑比较多&#xff0c;主要学习方式就是阅读官方文档和练习官方Demo。这里博主进行官方Demo的解读。 从gitee上克隆项目…

《PCI Express体系结构导读》随记 —— 第I篇 第1章 PCI总线的基本知识(15)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第I篇 第1章 PCI总线的基本知识&#xff08;14&#xff09; 1.3 PCI总线的存储器读写总线事务 1.3.4 PCI读写主存储器 前文已提到&#xff0c;由于本节内容较长&#xff0c;因此将后一部分内容放在本文中。 为…

基于Python、Keras和OpenCV的实时人脸活体检测

你在互联网上找到的大多数人脸识别算法和研究论文都遭受照片攻击。这些方法在检测和识别来自网络摄像头的图像、视频和视频流中的人脸方面非常有效。然而&#xff0c;他们无法区分现实生活中的面孔和照片上的面孔。这种无法识别人脸的现象是由于这些算法在二维帧上工作。 现在…

【JS笔记】JavaScript语法 《基础+重点》 知识内容,快速上手(二)

数组 什么是数组&#xff1f; 字面理解就是 数字的组合 其实不太准确&#xff0c;准确的来说数组是一个 数据的集合 也就是我们把一些数据放在一个盒子里面&#xff0c;按照顺序排好 [1, 2, 3, hello, true, false]这个东西就是一个数组&#xff0c;存储着一些数据的集合 …

深度学习框架Keras与Pytorch对比

对于许多科学家、工程师和开发人员来说&#xff0c;TensorFlow是他们的第一个深度学习框架。TensorFlow 1.0于2017年2月发布&#xff0c;可以说&#xff0c;它对用户不太友好。 在过去的几年里&#xff0c;两个主要的深度学习库Keras和Pytorch获得了大量关注&#xff0c;主要是…

【Java EE初阶五】wait及notify关键字

1. wait和notify的概念 所谓的wait和notify其实就是等待、通知机制&#xff1b;该机制的作用域join类似&#xff1b;由于多个线程之间是随机调度的&#xff0c;引入wait和notify就是为了能够从应用层面上&#xff0c;干预到多个不同线程代码的执行顺序&#xff0c;此处的干预&a…