当前位置: 首页 > article >正文

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

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

  • 1.[模板]前缀和
  • 2.【模板】二维前缀和
  • 3.寻找数组的中心下标
  • 4.除自身以外数组的乘积
  • 5.和为k的子数组
  • 6.和可被k整除的子数组
  • 7.连续数组
  • 8.矩阵区域和

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

http://www.kler.cn/a/377640.html

相关文章:

  • Docker打包自己项目推到Docker hub仓库(windows10)
  • C#如何封装将函数封装为接口dll?
  • 408 计算机组成原理、操作系统:异常和中断的总结
  • Java面向对象 C语言字符串常量
  • IDEA - 快速去除 mapper.xml 黄色警告线和背景色----简化版
  • 基于向量检索的RAG大模型
  • 对比C/C++语言,Rust语言有什么优势?
  • 关于爬虫需要了解的基础知识 (一、 http协议)
  • OceanBase数据库的使用(兼容MySQL)
  • SpringBoot篇(简化操作的原理)
  • 【数据结构】树-二叉树-堆(下)
  • 本地部署bert-base-chinese模型交互式问答,gradio
  • IDEA设置语法高亮自动检查xml中sql语法
  • Android13开发恢复出厂设置默认打开WiFi
  • 基于SSM+微信小程序的订餐管理系统(点餐2)
  • [算法初阶]第二集 滑动窗口
  • Google“Big Sleep“人工智能项目发现真实软件漏洞
  • 【算法赌场】区间合并
  • 传递悄悄话
  • java8有哪些新特性
  • 盘点谷歌全家桶中最值得付费的服务
  • 基于STL的自定义栈与队列实现:灵活选择底层容器的模板设计
  • 长度最小的子数组(滑动窗口)
  • cangjie仓颉程序设计-数据结构(四)
  • 无人机之远程指挥中心技术篇
  • 鸿蒙中的FA模型和Stage模型