算法练习:前缀和

目录

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

1. 一维前缀和

  1. 题目信息:
    在这里插入图片描述
  2. 题目链接:
    一维前缀和
  3. 思路:求前缀和数组,sum = dp[r] - dp[l - 1]
#include <iostream>
#include <vector>
using namespace std;int main() 
{int n = 0;int q = 0;cin >> n >> q;//先求前缀和数组int num = 0;//计算时可能溢出vector<long long> dp;dp.push_back(0);for(int i = 0; i < n; i++){cin >> num;dp.push_back(num + dp[i]);}//求询问区间之和//dp[i] - dp[i - 1]//计算时可能溢出vector<long long> ret;int left = 0,right = 0;for(int i = 0; i < q; i++){cin >> left >> right;ret.push_back(dp[right] - dp[left - 1]);}for(auto e : ret){cout << e << endl;}return 0;    
}

优化:

int main() 
{int n = 0;int q = 0;cin >> n >> q;//先求前缀和数组int num = 0;//默认初始化为0vector<int> arr(n + 1);for(int i = 1; i < n + 1; i++){cin >> num;arr[i] = num;}//防溢出vector<long long> dp(n + 1);for(int i = 1; i < n + 1; 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. 二维前缀和

  1. 题目信息:
    在这里插入图片描述
  2. 题目链接:
    二维前缀和
  3. 思路:二维前缀和

在这里插入图片描述

int main()
{int n = 0, m = 0, q = 0;//先遍历,得值    cin >> n >> m >> q;vector<vector<long long>> arr;vector<long long> part(m + 1);for (int i = 0; i < n + 1; i++){arr.push_back(part);}vector<vector<long long>> dp(arr);for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++){cin >> arr[i][j];}}//求前缀和数组for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++){dp[i][j] = arr[i][j] + dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1];}}//求区间值//x1,y1小,x2,y2大int x1, x2, y1, 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;
}

3. 寻找数组中心下标

  1. 题目信息:
    在这里插入图片描述
  2. 题目链接:
    寻找数组的中心下标
  3. 思路:正向与逆向前缀和数组,边界处理,特殊情况处理
class Solution
{
public:int pivotIndex(vector<int>& nums){int n = nums.size();vector<int> dp1(n);vector<int> dp2(n);//空if(nums.size() == 1){return 0;}int left = 0, right = nums.size() - 1;//求前缀和数组//顺序while (left < nums.size()){if (left > 0){dp1[left] = nums[left] + dp1[left - 1];}else{dp1[left] = nums[left];}left++;}//倒序while (right >= 0){if (right < nums.size() - 1){dp2[right] = nums[right] + dp2[right + 1];}else{dp2[right] = nums[right];}right--;}//遍历求中间结点for (int cur = 0; cur < nums.size(); cur++){//dp1顺序//dp2倒序if (cur == 0){if (dp2[cur + 1] == 0){return cur;}}else if (cur == nums.size() - 1){if (dp1[cur - 1] == 0){return cur;}}else{if (dp1[cur - 1] == dp2[cur + 1]){return cur;}}}return -1;}
};

优化:
在这里插入图片描述

class Solution 
{
public:int pivotIndex(vector<int>& nums) {int n = nums.size();//顺序vector<int> f(n);//逆序vector<int> g(n);//边界问题特殊处理f[0] = 0;//f[i] -> [0, i - 1]for(int i = 1; i < n; i++){f[i] = nums[i - 1] + f[i - 1];}g[n - 1] = 0;for(int i = n - 2; i >= 0; i--){g[i] = g[i + 1] + nums[i + 1];}for(int i = 0; i < n; i++){if(f[i] == g[i]){return i;}}return -1;}
};

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

  1. 题目信息:
    在这里插入图片描述
  2. 题目链接:
    除自身以外数组的乘积
  3. 思路:前缀 + 后缀数组
class Solution 
{
public:vector<int> productExceptSelf(vector<int>& nums) {int n = nums.size();vector<int> f(n);vector<int> g(n);f[0] = nums[0];for(int i = 1; i < n; i++){f[i] = nums[i] * f[i - 1];}g[n - 1] = nums[n - 1];for(int i = n - 2; i >= 0; i--){g[i] = nums[i] * g[i + 1];}vector<int> ret(n);for(int i = 0; i < n; i++){if(i == 0){ret[i] = g[i + 1];}else if(i == n - 1){ret[i] = f[i - 1];}else{ret[i] = g[i + 1] * f[i - 1];}}return ret;}
};

优化:
在这里插入图片描述

class Solution 
{
public:vector<int> productExceptSelf(vector<int>& nums) {int n = nums.size();vector<int> f(n);vector<int> g(n);f[0] = 1;//顺序for(int i = 1; i < n; i++){f[i] = f[i - 1] * nums[i - 1];}g[n - 1] = 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;}
};

5. !和为k的子数字

  1. 题目信息:
    在这里插入图片描述
  2. 题目链接:
    和为k的子数组
  3. 思路:前缀和,元素没有单调性,无法使用滑动窗口,逆向求sum - k,可以求得为i为尾的所有数组
class Solution 
{
public:int subarraySum(vector<int>& nums, int k) {int ret = 0;unordered_map<int ,int> hash;//sum - k == 0时,即sum就为khash[0] = 1;int sum = 0;//用哈希表代替遍历for(auto e : nums){sum += e;if(hash.count(sum - k)){ret += hash[sum - k];}//插入哈希表//可能存在重复前缀和hash[sum]++;}return ret;}
};

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

  1. 题目信息:
    在这里插入图片描述
  2. 题目链接:
    和可被k整除的子数组
  3. 思路:前缀和,哈希表,同余定理,C++中负数除以整数的余数修正(num % k + k) % k
class Solution 
{
public:int subarraysDivByK(vector<int>& nums, int k) {int sum = 0;unordered_map<int,int> hash;int ret = 0;int count = 0;//sum % k 本身就符合要求hash[0] = 1;for(auto e : nums){sum += e;//(sum1 - sum2) % k == 0//同余定理//负数除整数的余数//哈希表中存余数if(hash.count((sum % k + k) % k)){ret += hash[(sum % k + k) % k];}hash[(sum % k + k) % k]++;}return ret;}
};

7. !连续数组

  1. 题目信息:
    在这里插入图片描述
  2. 题目链接:
    连续数组
    3.思路:前缀加哈希表,求长度,记录下标
class Solution 
{
public:int findMaxLength(vector<int>& nums) {for(auto& e : nums){if(e == 0){e = -1;}}unordered_map<int,int> hash;int sum = 0;int len = 0;//细节,刚好sum为0hash[0] = -1;for(int i = 0; i < nums.size(); i++){//将所有的前缀和与对应下标记录至哈希表中sum += nums[i];//返回的是长度,最长数组的长度if(hash.count(sum) && len < i - hash[sum]){len = i - hash[sum];}//不存在添加下标if(!hash.count(sum)){hash[sum] = i;}}return len;}
};

@8. 矩阵区域和

  1. 题目信息:
    在这里插入图片描述
  2. 题目链接:
    矩阵区域和
  3. 思路:前缀和二维数组,边界问题分析

思路:
在这里插入图片描述
边界问题:
在这里插入图片描述

class Solution 
{
public:vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k){vector<int> part1(mat[0].size(), 0);vector<vector<int>> answer(mat.size(), part1);vector<int> part2(mat[0].size() + 1, 0);vector<vector<int>> dp(mat.size() + 1, part2);//二维数组的前缀和for (int i = 1; i < dp.size(); i++){for (int j = 1; j < dp[0].size(); j++){dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + mat[i - 1][j - 1];}}for (int i = 0; i < mat.size(); i++){for (int j = 0; j < mat[0].size(); j++){int sum = 0;//右下角//边界情况,修正int pos1 = i + k + 1;int pos2 = j + k + 1;if (pos1 >= dp.size()){pos1 = dp.size() - 1;}if (pos2 >= dp[0].size()){pos2 = dp[0].size() - 1;}sum += dp[pos1][pos2];//右上角pos1 = i - k;pos2 = j + k + 1;//i符合,j不符合if (pos1 >= 1 && pos2 >= dp[0].size()){pos2 = dp[0].size() - 1;}if (pos1 >= 1 && pos2 < dp[0].size()){sum -= dp[pos1][pos2];}//左下角pos1 = i + k + 1;pos2 = j - k;//i不符合,j符合if (pos1 >= dp.size() && pos2 >= 1){pos1 = dp.size() - 1;}if (pos1 < dp.size() && pos2 >= 1){sum -= dp[pos1][pos2];}//左上角if (i - k >= 1 && j - k >= 1){sum += dp[i - k][j - k];}answer[i][j] = sum;}}return answer;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/752914.shtml

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

相关文章

性能分析调优模型

性能测试除了为获取性能指标外&#xff0c;更多是为了发现性能瓶颈和性能问题&#xff0c;然后针对性能问题和性能瓶颈进行分析和调优。在当今互联网高速发展的时代&#xff0c;结合传统软件系统模型以及互联网网站特征&#xff0c;性能调优的模型可以归纳总结为如图1-5-1所示的…

多线程服务器适用场合

前提 进程”指的是fork(2)系统调用的产物 线程”指的是pthread_create()的产物,因此是宝贵的那种原生线程。而且Pthreads是NPTL的,每个线程由clone(2)产生,对应一个内核的task_struct。 Pthreads是一组线程操作的标准&#xff0c;NPTL是 Native POSIX Thread Library 的缩写&…

【Quixel Mixer】简单介绍

一、下载 官网下载地址&#xff1a;Quixel Mixer - All-in-one texturing & material creation tool 下载好之后双击exe来安装 等待安装完成 下载后打开&#xff0c;新建一个工程和Mix 二、界面介绍 我们先将软件界面分为如下3个部分 1号区域为菜单栏 2号区域介绍 2号…

单头注意力机制(ScaledDotProductAttention) python实现

输入是query和 key-value&#xff0c;注意力机制首先计算query与每个key的关联性&#xff08;compatibility&#xff09;&#xff0c;每个关联性作为每个value的权重&#xff08;weight&#xff09;&#xff0c;各个权重与value的乘积相加得到输出。 import torch import tor…

深入浅出理解 AI 生图模型

目录 引言 一、Stable Diffusion原理 首先 随后 最后 二、DDPM模型 1 资料 2 原理 扩散过程 反向过程 3 公式结论 三、优缺点 优点&#xff1a; 缺点&#xff1a; 四、改进与完事 LDM代表作 原理概括 Latent Space&#xff08;潜空间&#xff09; 五、总结 引…

MC0204 世界警察

世界警察小码哥来谈判了&#xff0c;恐怖分子在银行挟持了 n 个人质&#xff0c;每个人质都所属一个国家&#xff0c;第 i 个人质所属的国家为 ci​&#xff0c;人质排成了一排&#xff0c;位置都是固定的。经过商讨&#xff0c;恐怖分子允许小码哥可以带走任意一段连续区间内的…

关于大根堆,set重载运算符

题目描述 \,\,\,\,\,\,\,\,\,\,制定合理的日程能够帮助利用好时间进行加训&#xff0c;加训和加训。 \,\,\,\,\,\,\,\,\,\,新学期开始了&#xff0c;应该好好学习了&#xff01;凌晨两点整&#xff0c;加睡失败的你在为新一天的各项重要事件制定闹钟。 \,\,\,\,\,\,\,\,\,\, \,…

【SpringBoot】请求与响应参数 IoC与DI 总结

文章目录 ① —— 请求 ——一、简单参数 RequestParam1.1 参数与形参 命名相同1.2 参数与形参 命名不同 二、实体参数2.1 简单实体对象2.2 复杂实体对象 三、数组集合参数3.1 数组3.2 集合 RequestParam 四、日期参数 DateTimeFormat五、JSON参数 RequestBody六、路径参数 Pat…

docker镜像管理基础-3

文章目录 镜像的概念docker镜像层docker存储驱动AUFSOverlayFSDeviceMapper docker registrydocker镜像的制作Docker Hubdocker镜像的获取镜像的生成基于容器制作镜像 镜像的导入与导出 镜像的概念 镜像可以理解为应用程序的集装箱&#xff0c;而docker用来装卸集装箱。 docke…

代码+视频,R语言使用BOOT重抽样获取cox回归方程C-index(C指数)可信区间

bootstrap自采样目前广泛应用与统计学中&#xff0c;其原理很简单就是通过自身原始数据抽取一定量的样本&#xff08;也就是取子集&#xff09;&#xff0c;通过对抽取的样本进行统计学分析&#xff0c;然后继续重新抽取样本进行分析&#xff0c;不断的重复这一过程N&#xff0…

Android的三种动画详解(帧动画,View动画,属性动画)

Android的三种动画详解&#xff08;帧动画、View动画、属性动画&#xff09;_android动画效果大全-CSDN博客 1、帧动画 缺点是&#xff1a;占用内存较高&#xff0c;播放的是一帧一帧的图片&#xff0c;很少使用。 顺序播放预先定义的图片&#xff0c;类似于播放视频。 步骤…

代码随想录阅读笔记-字符串【替换数字】

题目 给定一个字符串 s&#xff0c;它包含小写字母和数字字符&#xff0c;请编写一个函数&#xff0c;将字符串中的字母字符保持不变&#xff0c;而将每个数字字符替换为number。 例如&#xff0c;对于输入字符串 "a1b2c3"&#xff0c;函数应该将其转换为 "anu…

PlayBook 详解

4&#xff09;Playbook 4.1&#xff09;Playbook 介绍 PlayBook 与 ad-hoc 相比&#xff0c;是一种完全不同的运用 Ansible 的方式&#xff0c;类似与 Saltstack 的 state 状态文件。ad-hoc 无法持久使用&#xff0c;PlayBook 可以持久使用。 PlayBook 剧本是 由一个或多个 “…

Linux之shell变量

华子目录 什么是变量&#xff1f;变量的名称示例 变量的类型变量的定义示例 自定义变量查看变量&#xff08;自定义变量和全局变量&#xff09; 环境变量定义环境变量&#xff08;全局变量&#xff09;法一法二法三env&#xff0c;printenv&#xff0c;export注意 C语言与shell…

upload-labs 0.1 靶机详解

下载地址https://github.com/c0ny1/upload-labs/releases Pass-01 他让我们上传一张图片&#xff0c;我们先尝试上传一个php文件 发现他只允许上传图片格式的文件&#xff0c;我们来看看源码 我们可以看到它使用js来限制我们可以上传的内容 但是我们的浏览器是可以关闭js功能的…

蓝桥杯-粘木棍-DFS

题目 思路 --有n根木棍&#xff0c;需要将其粘成m根木棍&#xff0c;并求出最小差值&#xff0c;可以用DFS枚举出所有情况。粘之前有n根短木棍&#xff0c;粘之后有m根长木棍&#xff0c;那么让长木棍的初始长度设为0。外循环让所有的短木棍都参与粘&#xff0c;内循环让要粘的…

windows 11访问Debian10上的共享目录

步骤 要在Windows 11上访问Debian 10.0.0的共享目录&#xff0c;可以通过以下步骤来实现&#xff1a; 1. 设置Samba服务&#xff1a;在Debian系统上&#xff0c;需要安装并配置Samba服务&#xff0c;以便能够实现文件夹共享。Samba是一个允许Linux/Unix服务器与Windows操作系…

2024年阿里云数据库价格_云数据库收费标准最新

2024年阿里云数据库价格查询&#xff0c;云数据库优惠活动MySQL版2核2GB 50GB配置99元一年&#xff0c;续费不涨价&#xff0c;续费也是99元1年&#xff0c;云数据库MySQL基础系列经济版 2核4GB 100GB配置227元1年&#xff0c;RDS SQL Server云数据库2核4G配置299元1年&#xf…

【CSS】Vue2使用TailwindCSS方法及相关问题

一.安装 1.npm安装TailwindCSS npm install tailwindcssnpm:tailwindcss/postcss7-compat tailwindcss/postcss7-compat postcss^7 autoprefixer^9 2.创建配置文件 npx tailwindcss init 3.创建postcss.config.js文件 // postcss.config.js module.exports {plugins: {t…

git的下载与安装

下载 首先&#xff0c;打开您的浏览器&#xff0c;并输入Git的官方网站地址 点击图标进行下载 下载页面会列出不同操作系统和平台的Git安装包。根据您的操作系统&#xff08;Windows、macOS、Linux等&#xff09;和位数&#xff08;32位或64位&#xff09;&#xff0c;选择适…