前缀和算法:算法秘籍下的数据预言家

2024-06-14 21:52

本文主要是介绍前缀和算法:算法秘籍下的数据预言家,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

✨✨✨学习的道路很枯燥,希望我们能并肩走下来!

文章目录

目录

文章目录

前言

一. 前缀和算法的介绍

二、前缀和例题

2.1 【模版】前缀和

2.2 【模板】二维前缀和

 2.3 寻找数组的中间下标

 2.4 除自身以外数组的乘积

 2.5 和为k的子数组

2.6 和可被k整除的子数组

 2.7 连续数组

 2.8 矩阵区域和

总结


前言

本篇详细介绍了前缀和算法的使用,让使用者了解前缀和,而不是仅仅停留在表面, 文章可能出现错误,如有请在评论区指正,让我们一起交流,共同进步!


一. 前缀和算法的介绍

前缀和算法是一种用空间换时间的算法,他常常用于解决某些题目或者作为某些高级算法的组成部分。

例如:让你求某个矩阵(一维)的子矩阵的最大值,如果使用暴力解法它的时间复杂度将会是O(n^2) ,但如果使用该算法就可以使其时间复杂度降低一个维度也就是O(N).

前缀和 是从 nums 数组中的第 0 位置开始累加,到第 𝑖位置的累加结果,我们常把这个结果保存到数组 Sum 中,记为 Sum[i]。 

前缀和算法的本质是一个简单动态规划

 接下来我们使用一些例题来介绍一下

二、前缀和例题

2.1 【模版】前缀和

牛客网—【模版】前缀和

 

#include <iostream>
#include<vector>
using namespace std;int main() {//1.读入数据int n ,q;cin>>n>>q;vector<int> arr(n+1);for(int i = 1;i<=n;i++) cin>>arr[i];//2. 预处理出来个前缀和数组vector<long long> dp(n+1); //防止溢出for(int i = 1;i<=n;i++) dp[i] = dp[i-1]+arr[i];//3.使用前缀和数组int l = 0, r = 0;while(q--){cin>>l>>r;cout<<dp[r]-dp[l-1]<<endl;}return 0;}

2.2 【模板】二维前缀和

牛客网—【模版】二维前缀和

 

#include <iostream>
#include <vector>
using namespace std;int main() {int n,m,q;cin>>n>>m>>q;vector<vector<int>> arr(n+1,vector<int>(m+1));for(int i = 1;i<=n;i++){for(int j = 1;j<=m;j++){cin>>arr[i][j];}}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-1][j] + dp[i][j-1] + arr[i][j] - dp[i-1][j-1];}}int x1 = 0,y1 = 0,x2 = 0 ,y2 = 0;while(q--){cin>>x1>>y1>>x2>>y2;cout<<dp[x2][y2] - dp[x1-1][y2] - dp[x2][y1-1] + dp[x1-1][y1-1]<<endl;}return 0;
}

 2.3 寻找数组的中间下标

724. 寻找数组的中心下标 - 力扣(LeetCode) 

 

class Solution {
public:int pivotIndex(vector<int>& nums) {int n = nums.size();vector<int> f(n), g(n);//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];//2. 使用for(int i = 0;i<n;i++)if(f[i] == g[i]) return i;return -1;}
};

 2.4 除自身以外数组的乘积

238. 除自身以外数组的乘积 - 力扣(LeetCode) 

class Solution {
public:vector<int> productExceptSelf(vector<int>& nums) {int n = nums.size();//细节处理vector<int> f(n,1), g(n,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];//使用vector<int> ret(n);for(int i = 0;i<n;i++)ret[i] = f[i] * g[i];return ret;}
};

 2.5 和为k的子数组

560. 和为 K 的子数组 - 力扣(LeetCode)

 

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&x : nums){sum+=x; //计算当前位置的前缀和if(hash.count(sum-k)) ret+=hash[sum-k]; //统计个数hash[sum]++;}return ret;}
};

2.6 和可被k整除的子数组

974. 和可被 K 整除的子数组 - 力扣(LeetCode) 

 

class Solution {
public:int subarraysDivByK(vector<int>& nums, int k) {unordered_map<int,int> hash;hash[0 % k] = 1; //0 这个数的余数int sum = 0, ret = 0;for(auto& x : nums){sum+=x; //算出当前位置的前缀和if(hash.count((sum%k+k)%k)) ret+=hash[(sum%k+k)%k]; //修正后的余数+统计结果hash[(sum%k+k)%k]++;}return ret;}
};

 2.7 连续数组

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

 

class Solution {
public:int findMaxLength(vector<int>& nums) {unordered_map<int,int> hash;hash[0] = -1; //默认有一个前缀和为0的情况int sum = 0, ret = 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;}
};

 2.8 矩阵区域和

1314. 矩阵区域和 - 力扣(LeetCode)

 

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));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];vector<vector<int>> answer(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;int y1 = max(0,j-k)+1;int x2 = min(m-1,i+k)+1;int y2 = min(n-1,j+k)+1;answer[i][j] = dp[x2][y2] - dp[x1-1][y2] - dp[x2][y1-1] + dp[x1-1][y1-1];}return answer;}
};

总结

✨✨✨各位读友,本篇分享到内容是否更好的让你理解前缀和算法,如果对你有帮助给个👍赞鼓励一下吧!!
🎉🎉🎉世上没有绝望的处境,只有对处境绝望的人。
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!

这篇关于前缀和算法:算法秘籍下的数据预言家的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1061606

相关文章

【服务器运维】MySQL数据存储至数据盘

查看磁盘及分区 [root@MySQL tmp]# fdisk -lDisk /dev/sda: 21.5 GB, 21474836480 bytes255 heads, 63 sectors/track, 2610 cylindersUnits = cylinders of 16065 * 512 = 8225280 bytesSector size (logical/physical)

代码随想录算法训练营:12/60

非科班学习算法day12 | LeetCode150:逆波兰表达式 ,Leetcode239: 滑动窗口最大值  目录 介绍 一、基础概念补充: 1.c++字符串转为数字 1. std::stoi, std::stol, std::stoll, std::stoul, std::stoull(最常用) 2. std::stringstream 3. std::atoi, std

人工智能机器学习算法总结神经网络算法(前向及反向传播)

1.定义,意义和优缺点 定义: 神经网络算法是一种模仿人类大脑神经元之间连接方式的机器学习算法。通过多层神经元的组合和激活函数的非线性转换,神经网络能够学习数据的特征和模式,实现对复杂数据的建模和预测。(我们可以借助人类的神经元模型来更好的帮助我们理解该算法的本质,不过这里需要说明的是,虽然名字是神经网络,并且结构等等也是借鉴了神经网络,但其原型以及算法本质上还和生物层面的神经网络运行原理存在

SQL Server中,查询数据库中有多少个表,以及数据库其余类型数据统计查询

sqlserver查询数据库中有多少个表 sql server 数表:select count(1) from sysobjects where xtype='U'数视图:select count(1) from sysobjects where xtype='V'数存储过程select count(1) from sysobjects where xtype='P' SE

数据时代的数字企业

1.写在前面 讨论数据治理在数字企业中的影响和必要性,并介绍数据治理的核心内容和实践方法。作者强调了数据质量、数据安全、数据隐私和数据合规等方面是数据治理的核心内容,并介绍了具体的实践措施和案例分析。企业需要重视这些方面以实现数字化转型和业务增长。 数字化转型行业小伙伴可以加入我的星球,初衷成为各位数字化转型参考库,星球内容每周更新 个人工作经验资料全部放在这里,包含数据治理、数据要

如何在Java中处理JSON数据?

如何在Java中处理JSON数据? 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将探讨在Java中如何处理JSON数据。JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,在现代应用程序中被广泛使用。Java通过多种库和API提供了处理JSON的能力,我们将深入了解其用法和最佳

大林 PID 算法

Dahlin PID算法是一种用于控制和调节系统的比例积分延迟算法。以下是一个简单的C语言实现示例: #include <stdio.h>// DALIN PID 结构体定义typedef struct {float SetPoint; // 设定点float Proportion; // 比例float Integral; // 积分float Derivative; // 微分flo

两个基因相关性CPTAC蛋白组数据

目录 蛋白数据下载 ①蛋白数据下载 1,TCGA-选择泛癌数据  2,TCGA-TCPA 3,CPTAC(非TCGA) ②蛋白相关性分析 1,数据整理 2,蛋白相关性分析 PCAS在线分析 蛋白数据下载 CPTAC蛋白组学数据库介绍及数据下载分析 – 王进的个人网站 (jingege.wang) ①蛋白数据下载 可以下载泛癌蛋白数据:UCSC Xena (xena

LeetCode 算法:二叉树的中序遍历 c++

原题链接🔗:二叉树的中序遍历 难度:简单⭐️ 题目 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 示例 1: 输入:root = [1,null,2,3] 输出:[1,3,2] 示例 2: 输入:root = [] 输出:[] 示例 3: 输入:root = [1] 输出:[1] 提示: 树中节点数目在范围 [0, 100] 内 -100 <= Node.

【Java算法】滑动窗口 下

​ ​    🔥个人主页: 中草药 🔥专栏:【算法工作坊】算法实战揭秘 🦌一.水果成篮 题目链接:904.水果成篮 ​ 算法原理 算法原理是使用“滑动窗口”(Sliding Window)策略,结合哈希表(Map)来高效地统计窗口内不同水果的种类数量。以下是详细分析: 初始化:创建一个空的哈希表 map 用来存储每种水果的数量,初始化左右指针 left