优选算法第四讲:前缀和模块

1.[模板]前缀和

链接: link
在这里插入图片描述

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

int main() {
    
    
    int n = 0, q = 0;
    cin >> n >> q;
    vector<int> arr(n+1);//开辟一个n+1的数组
    for(int i = 1; i <= n; i++) cin >> arr[i];
    
    //创建一个前缀和数组。vector的构造会自己初始化
    vector<long long> dp(n+1);
    //更新前缀和数组
    for(int i = 1; i<=n; i++) dp[i] = dp[i-1] + arr[i];

    //直接使用前缀和数组进行返回即可
    int l = 0, r = 0;
    while(q--)
    {
    
    
        cin >> l >> r;
        cout << dp[r] - dp[l-1] << endl;//直接输出结果即可
    }
    return 0;
}

2.【模板】二维前缀和

链接: link
在这里插入图片描述

3.寻找数组的中心下标

链接: link
在这里插入图片描述

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;
    }
};

4.除自身以外数组的乘积

链接: link
在这里插入图片描述

class Solution {
    
    
public:
    vector<int> productExceptSelf(vector<int>& nums) {
    
    
        int n = nums.size();
        vector<int> f(n), g(n);
        
        //1.先求出f和g数组
        f[0] = 1;//注意:细节问题一定要处理
        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];

        //2.使用两数组
        vector<int> ret(n);
        for(int i = 0; i<n; i++)
            ret[i] = f[i] * g[i];

        return ret;
    }
};

5.和为k的子数组

链接: link
在这里插入图片描述

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

6.和可被k整除的子数组

链接: link
在这里插入图片描述

class Solution {
    
    
public:
    int subarraysDivByK(vector<int>& nums, int k) {
    
    
        unordered_map<int, int> hash;
        hash[0] = 1;//细节问题:如果nums的和可被k整除,那么也要将次数+1

        int sum = 0, ret = 0;
        for(auto e : nums)
        {
    
    
            sum += e;
            int r = (sum%k + k) % k;//求余数的方法
            if(hash.count(r)) ret += hash[r];//如果sum%k = 前缀和%k,那么就可以被k整除
            hash[r]++;
        }

        return ret;
    }
};

7.连续数组

链接: link
在这里插入图片描述

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

        int sum = 0, ret = 0;
        for(int i = 0; i<nums.size(); i++)
        {
    
    
            sum += nums[i] == 0 ? -1 : 1;//我们不需要将数组的0改为1,只需要在加的这个部分加-1就行了
            if(hash.count(sum)) ret = max(ret, i-hash[sum]);
            else hash[sum] = i;//此时存储的应该是下标
        }

        return ret;
    }
};

8.矩阵区域和

链接: link
在这里插入图片描述

class Solution {
    
    
public:
    vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) {
    
    
        int m = 0, n = 0;
        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>> ret(m, vector<int>(n));
        for(int i = 0; i<m; i++)
        {
    
    
            for(int j = 0; j<n; j++)
            {
    
    
                int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
                x1 = max(0, i-k) + 1;
                y1 = max(0, j-k) + 1;
                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;
    }
};

猜你喜欢

转载自blog.csdn.net/2301_79761834/article/details/143272875