前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【数据结构与算法】前缀和

【数据结构与算法】前缀和

作者头像
风中的云彩
发布于 2025-05-22 00:43:54
发布于 2025-05-22 00:43:54
6100
代码可运行
举报
文章被收录于专栏:C/C++的自学之路C/C++的自学之路
运行总次数:0
代码可运行

前言

这是我自己学习蓝桥杯算法的第四篇博客总结。 上一期笔记是关于二分查找算法,没看的同学可以过去看看: 【数据结构与算法】二分查找_.二分查找c++-CSDN博客

https://cloud.tencent.com/developer/article/2519670

技巧

一维数组前缀和

前缀和算法快速求出数组中某一连续区间的和。 原来的数组为numsn,新创建一个前缀和数组dpn,则有dpi=dpi-1+numsi。 如果原来的数组下标是从1开始,那么前缀和数组下标也从1开始,可以避免处理边界条件前缀和也可以变形成后缀和

二维数组前缀和

前缀和算法快速求出数组中某一矩阵区间的和。 原来的数组为numsn,新创建一个前缀和数组dpn,则有dpn=dpn-1+dpn+numsn-dpn-1。 如果原来的数组下标是从1开始,那么前缀和数组下标也从1开始,可以避免处理边界条件

例题

nowcoder-dp34题:undefined【模板】前缀和_牛客题霸_牛客网

https://www.nowcoder.com/practice/acead2f4c28c401889915da98ecdc6bf?tpId=230&tqId=2021480&ru=/exam/oj&qru=/ta/dynamic-programming/question-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E7%25AE%2597%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D196

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
using namespace std;

int main()
{
    int n=0,m=0,l=0,r=0;
    long long arr[100001]={0};
    long long dp[100001]={0};
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>arr[i];
    for(int i=1;i<=n;i++)
        dp[i]=dp[i-1]+arr[i];
    while(m--)
    {
        cin>>l>>r;
        cout<<dp[r]-dp[l-1]<<endl;
    }
    return 0;
}

nowcoder-dp35题:undefined【模板】二维前缀和_牛客题霸_牛客网

https://www.nowcoder.com/practice/99eb8040d116414ea3296467ce81cbbc?tpId=230&tqId=2023819&ru=/exam/oj&qru=/ta/dynamic-programming/question-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E7%25AE%2597%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D196

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
using namespace std;

int main() 
{
    int n=0,m=0,q=0;
    long long nums[2000][2000]={0};
    long long dp[2000][2000]={0};
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
            cin>>nums[i][j];
    }
    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]-dp[i-1][j-1]+nums[i][j];
    }
    while(q--)
    {
        int x1=0,y1=0,x2=0,y2=0;
        cin>>x1>>y1>>x2>>y2;
        long long ret=dp[x2][y2]-dp[x1-1][y2]-dp[x2][y1-1]+dp[x1-1][y1-1];
        cout<<ret<<endl;
    }
    return 0;
}

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

https://leetcode.cn/problems/find-pivot-index/description/

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    int pivotIndex(vector<int>& nums) 
    {
        int left=0,right=nums.size(),cur=0;
        int dp[20000]={0};
        dp[0]=nums[0];
        for(int i=1;i<right;i++)
        {
            dp[i]=dp[i-1]+nums[i];
        }
        while(cur<right)
        {   
            if(cur==0&&0==dp[right-1]-dp[cur])
                return 0;
            else if(cur!=0&&dp[cur-1]==dp[right-1]-dp[cur])
                return cur;
            else
                cur++;
        }
        return -1;
    }
};

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

https://leetcode.cn/problems/product-of-array-except-self/

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) 
    {
        int end=nums.size()-1;
        vector<int> dp_front(nums.size(),0);
        vector<int> dp_back(nums.size(),0);
        vector<int> answer(nums.size(),0);
        dp_front[0]=nums[0];
        dp_back[end]=nums[end];
        for(int i=1;i<=end;i++)
            dp_front[i]=dp_front[i-1]*nums[i];
        for(int i=end-1;i>=0;i--)
            dp_back[i]=dp_back[i+1]*nums[i];
        answer[0]=dp_back[1];
        answer[end]=dp_front[end-1];
        for(int i=1;i<end;i++)
            answer[i]=dp_front[i-1]*dp_back[i+1];
        return answer;
    }
};

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

https://leetcode.cn/problems/subarray-sum-equals-k/description/

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    int subarraySum(vector<int>& nums, int k) 
    {
        unordered_map<int,int> m;
        m[0]=1;
        int count=0,i=0,sum=0;
        while(i<nums.size())
        {
            sum+=nums[i];
            int remainder=sum-k;
            if(m.find(remainder)!=m.end())
                count+=m[remainder];
            m[sum]++;
            i++;
        }
        return count;
    }
};

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

https://leetcode.cn/problems/subarray-sums-divisible-by-k/

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    int subarraysDivByK(vector<int>& nums, int k) 
    {
        unordered_map<int,int> m;
        m[0]=1;
        int sum=0,i=0,count=0;
        while(i<nums.size())
        {
            sum+=nums[i];
            int remainder=(sum%k+k)%k;
            if(m.find(remainder)!=m.end())
                count+=m[remainder];
            m[remainder]++;
            i++;
        }
        return count;
    }
};

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

https://leetcode.cn/problems/contiguous-array/

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    int findMaxLength(vector<int>& nums) 
    {
        unordered_map<int,int> m;
        int length=0,i=0,sum=0;
        m[0]=0;
        while(i<nums.size())
        {
            if(nums[i]==0)
                sum+=-1;
            else
                sum+=1;
            if(m.find(sum)!=m.end())
                length=max(length,i+1-m[sum]);
            else
                m[sum]=i+1;
            i++;
        }
        return length;
    }
};

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-05-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验