带你手撕前缀和

华为实习技术面手撕代码 手撕代码–任务调度器(Leecode 621): 给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间,CPU 可以完成一个任务,或者处于待命状态。 然而,两个 相同种类 的任务之间必须有长度为整数 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。 你需要计算完成所有任务所需要的 最短时间 。 力扣(LeetCode) 基本思 阅读详情

带你手撕前缀和

参考

link

link1

构造二维前缀和的三种方法

  • 先计算第一行与第一列再进行别的计算
  • 先固定行计算每一行的前缀和,再固定相应行的列的前缀和
  • 增加一维直接计算 pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+data[i][j]

不说了上代码

// 这里讲的是二维的差分数组的应用

#include <iostream>
#include <vector>

using namespace std;

vector<vector<int>> GetSum1(const vector<vector<int>>& data) {
  int n = data.size();
  int m = data[0].size();
  auto prefix_sum = data;

  // 这个就是先求第一行第一列再求剩余的
  for (int i = 1; i < m; i++) {
    prefix_sum[0][i] = prefix_sum[0][i - 1] + prefix_sum[0][i];
  }

  for (int i = 1; i < n; i++) {
    prefix_sum[i][0] = prefix_sum[i][0] + prefix_sum[i - 1][0];
  }

  // 开始处理
  for (int i = 1; i < n; i++) {
    for (int j = 1; j < m; j++) {
      prefix_sum[i][j] = prefix_sum[i - 1][j] + prefix_sum[i][j - 1] -
                         prefix_sum[i - 1][j - 1] + data[i][j];
    }
  }
  return prefix_sum;
}

vector<vector<int>> GetSum2(
    const vector<vector<int>>& data) {  // 这是用固定行列的方法计算出来的
  int n = data.size();
  int m = data[0].size();
  auto prefix_sum = data;
  // 先固定行

  for (int i = 0; i < n; i++) {
    for (int j = 1; j < m; j++) {
      prefix_sum[i][j] = prefix_sum[i][j - 1] + prefix_sum[i][j];
    }
  }

  // 再固定列

  for (int j = 0; j < m; j++) {
    for (int i = 1; i < n; i++) {
      prefix_sum[i][j] = prefix_sum[i][j] + prefix_sum[i - 1][j];
    }
  }
  return prefix_sum;
}

vector<vector<int>> GetSum3(const vector<vector<int>>& data) {
  int n = data.size();
  int m = data[0].size();
  // 这个就是增加一维来进行处理
  vector<vector<int>> prefix_sum(n + 1, vector<int>(m + 1, 0));

  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      prefix_sum[i][j] = prefix_sum[i - 1][j] + prefix_sum[i][j - 1] -
                         prefix_sum[i - 1][j - 1] + data[i - 1][j - 1];
    }
  }
  return prefix_sum;
}

int GetArea(vector<vector<int>>& data, int x1, int y1, int x2, int y2) {
  // 函数是找到左上角为(x1,y1)右下角为(x2,y2)的数字的和
  if (x1 < 0 || y1 < 0 || x2 >= data.size() ||
      y2 >= data[0].size()) {  // 不合理
    return -1;
  }
}

void Show(vector<vector<int>>& data) {
  for (auto a : data) {
    for (auto b : a) {
      cout << b << " ";
    }
    cout << endl;
  }
  cout << "================" << endl;
}

int main() {
  vector<vector<int>> data = {{1, 2, 3, 4}, {5, 6, 7, 8}};
  Show(data);
  auto prefix_1 = GetSum1(data);
  Show(prefix_1);

  auto prefix_2 = GetSum2(data);
  Show(prefix_2);

  auto prefix_3 = GetSum3(data);
  Show(prefix_3);
}

结果

1 2 3 4 
5 6 7 8 
================
1 3 6 10 
6 14 24 36 
================
1 3 6 10 
6 14 24 36 
================
0 0 0 0 0 
0 1 3 6 10 
0 6 14 24 36 
================

其中

方法一

vector<vector<int>> GetSum1(const vector<vector<int>>& data) {
  int n = data.size();
  int m = data[0].size();
  auto prefix_sum = data;

  // 这个就是先求第一行第一列再求剩余的
  for (int i = 1; i < m; i++) {
    prefix_sum[0][i] = prefix_sum[0][i - 1] + prefix_sum[0][i];
  }

  for (int i = 1; i < n; i++) {
    prefix_sum[i][0] = prefix_sum[i][0] + prefix_sum[i - 1][0];
  }

  // 开始处理
  for (int i = 1; i < n; i++) {
    for (int j = 1; j < m; j++) {
      prefix_sum[i][j] = prefix_sum[i - 1][j] + prefix_sum[i][j - 1] -
                         prefix_sum[i - 1][j - 1] + data[i][j];
    }
  }
  return prefix_sum;
}

方法二

vector<vector<int>> GetSum2(
    const vector<vector<int>>& data) {  // 这是用固定行列的方法计算出来的
  int n = data.size();
  int m = data[0].size();
  auto prefix_sum = data;
  // 先固定行

  for (int i = 0; i < n; i++) {
    for (int j = 1; j < m; j++) {
      prefix_sum[i][j] = prefix_sum[i][j - 1] + prefix_sum[i][j];
    }
  }

  // 再固定列

  for (int j = 0; j < m; j++) {
    for (int i = 1; i < n; i++) {
      prefix_sum[i][j] = prefix_sum[i][j] + prefix_sum[i - 1][j];
    }
  }
  return prefix_sum;
}

方法三

vector<vector<int>> GetSum3(const vector<vector<int>>& data) {
  int n = data.size();
  int m = data[0].size();
  // 这个就是增加一维来进行处理
  vector<vector<int>> prefix_sum(n + 1, vector<int>(m + 1, 0));

  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      prefix_sum[i][j] = prefix_sum[i - 1][j] + prefix_sum[i][j - 1] -
                         prefix_sum[i - 1][j - 1] + data[i - 1][j - 1];
    }
  }
  return prefix_sum;
}

例题

link

LeetCode刷题攻略:从零基础到搞定大厂手撕代码 本文提供了一份全面的LeetCode刷题攻略,帮助读者从零基础逐步掌握算法思维,最终能够轻松应对大厂手撕代码的挑战。内容涵盖基础数据结构、算法范式、科学刷题方法以及面试实战技巧,特别适合准备技术面试的开发者。 阅读详情

相关推荐

2025华为OD面试手撕代码真题目录及面试八股文

本专栏更新每年华为OD机试的高频手撕代码题,每个题目都会使用五种语言进行解答(C & C++& Java & Python & JS) 华为od机试,华为od机试真题,华为od机试E卷,华为odE卷,华为od机试真题E卷,华为OD,华为OD机试,华为OD机试真题,华为od机考,华为od机试D卷,华为od机试真题D卷,华为od手撕代码,华为od,华为od机试C卷,华为od e卷,华为2024e卷,od机试,2024E卷,华为OD机试E卷,什么是华为od,华为od介绍,全面了解华为od,2024华为od,如何备

KJ.JK 5万+

手撕算法 ——前缀和

本文介绍前缀和相关算法,包括一维、二维前缀和及最大子段和、激光炸弹问题。一维前缀和可解决数组区间和问题,暴力法时间复杂,前缀和法通过创建数组 `f[i]=f[i−1]+a[i]` 快速求解,查询为 `f[r]−f[l−1]`;最大子段和通过前缀和数组,减前驱最小值求;二维前缀和可求子矩阵元素和,暴力法遍历慢,前缀和法套公式创建矩阵求解;激光炸弹用二维矩阵存目标价值,求前缀和矩阵,枚举边长为 `R` 子正方形最大值,注意位置重复和 `R` 超范围情况,各有参考代码。

阳光开朗大男孩 = ̄ω ̄=的博客 1507

华为OD面试手撕真题目录

2026最新华为OD面试手撕真题 , 提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解.

qq_45776114的博客 1万+

【算法】【前缀和】核心原理、大厂高频考点、三语言实现、面试手撕技巧

前缀和算法解析与面试应用 前缀和通过预处理数组实现O(1)区间查询,核心是构建preSum数组(preSum[i] = preSum[i-1] + nums[i-1])。适用于静态数据高频求和场景,复杂度:预处理O(n),查询O(1)。典型应用包括子数组和问题(如LeetCode 560)及二维矩阵求和(LeetCode 304)。大厂常考变形题如将平均数问题转化为和为0的最长子数组。提供Python/Java/C++三语言实现模板,并强调面试需注意边界条件(如preSum[0]=0)和动态数据改用线段树。

学习代码 1093

【华为OD技术面试手撕真题】1、长度最小的子数组 | 手撕真题+思路参考+代码解析(C & C++ & Java & Python & JS)(三种解法)

【华为OD面试手撕真题】长度最小的子数组,本专栏更新每年华为OD机试的高频手撕代码题,每个题目都会使用五种语言进行解答(C & C++& Java & Python & JS),思路分析都非常详细, 实现最低的时间复杂度和高通过率,每个解题思路超过百字,内含各个编程语言的八股文面试题,欢迎大家订阅学习, 代码可以直接运行使用,全网限时最低价,持续更新

KJ.JK 1万+

【华为OD技术面试手撕真题】22、最长公共前缀 | 手撕真题+思路参考+代码解析(C & C++ & Java & Python & JS) 0ms耗时

【华为OD技术面试手撕真题】22、最长公共前缀 | 手撕真题+思路参考+代码解析(C & C++ & Java & Python & JS)华为od机试真题,华为OD技术二面,华为od机考,华为od手撕真题,华为od技术二面,华为od机试,华为OD机试的高频手撕代码题,华为od八股文

KJ.JK 3909

一篇带你速通前缀和算法(C/C++)

前缀和是一种常见的算法计算技巧,通常用于处理数组或序列的连续子区间求和问题。它可以帮助我们在 O(1) 的时间内计算出指定子区间的和,而不需要每次都遍历整个子区间。前缀和一般用于预处理当中,具有高效率的特点。

闻道有先后,术业有专攻 4087

【华为OD技术面试手撕真题】68、和为K的子数组 | 手撕真题+思路参考+代码解析(C & C++ & Java & Python & JS)

【华为OD技术面试手撕真题】68、和为 K 的子数组 | 手撕真题+思路参考+代码解析(C & C++ & Java & Python & JS) 华为od机试,华为od机试真题,华为od机试E卷,华为odE卷,华为od机试真题E卷,华为OD,华为OD机试,华为OD机试真题,华为od机考,华为od机试D卷,华为od机试真题D卷,华为od手撕代码,华为od,华为od机试C卷,华为od e卷,华为2024e卷,od机试,2024E卷,华为OD机试E卷,什么是华为od,华为od介绍,全面了解华为od,2024华为

KJ.JK 5289

手撕算法——差分

博客主要介绍了差分算法相关内容,包括一维差分、海底高铁(涉及一维差分应用)、二维差分及地毯(二维差分应用)。 一维差分可用于处理区间修改问题,通过创建差分数组,利用其性质处理区间修改,最后通过前缀和还原原始数组。海底高铁问题则是利用差分数组计算高铁乘坐次数,进而求出最小花费。二维差分是一维差分的扩展,通过类比推导出二维差分矩阵的性质,可用于处理二维矩阵的区间修改问题,同样通过前缀和还原原始矩阵。地毯问题直接利用二维差分矩阵解决。这些内容通过具体的题目描述、算法原理及参考代码进行了详细讲解。

阳光开朗大男孩 = ̄ω ̄=的博客 1104

【研发岗】华为OD手撕代码 - 和为 K 的子数组

给定一个整数数组和一个整数 k ,请找到该数组中和为 k 的连续子数组的个数。实例1:输入:nums = [1,1,1], k = 2输出: 2解释: 此题 [1,1] 与 [1,1] 为两种不同的情况实例2:输入:nums = [1,2,3], k = 3输出: 2。

学习,你不是一个人在战斗 ~ 961302305(QQ,微信) 215

用Multisim和74HC系列芯片,手把手教你搭建一个能“算数”的简易CPU模型

本文详细介绍了如何使用Multisim仿真软件和74HC系列芯片搭建一个简易CPU模型,重点解析了74HC194寄存器和74HC283加法器的核心功能与连接方法。通过分步图解和实战调试,帮助读者理解CPU工作原理,掌握数字电路设计的基本技能,适合计算机组成原理初学者和电子爱好者实践学习。

weixin_26843605的博客 140

华为OD-Python手撕算法题集合

或者去B站搜博主-代码随想录 看卡哥的讲解视频,个人感觉卡哥讲得确实很通透仔细。友情提醒:大家准备手撕和机考题目是可以优先多刷一刷力扣hot100的题目,基础较弱的同学可以去(

qq_16835203的博客 218

ERA5 数据集下载(2025最新 可运行)

众所周知,ERA5数据集经过了更新,尤其是在API访问和下载方式上发生了变化。2025年版的ERA5数据集为气象研究人员提供了更高质量的历史气象数据。本文将介绍如何通过新的API接口下载最新的ERA5数据集。

m0_72141699的博客 3597

手撕算法之前缀和

对一个二维数组按照行或者列一分为二,要求使得两个部分的元素和差值最小。也是按照行和列对原数组进行求部分和,然后直接对部分和数组进行遍历求差值。当需要对数组进行区间的求和操作时,为了节约资源,我们可以将数组的部分和提前计算并储存到一个新数组中。当需要进行区间运算时,我们只需要进行部分和的运算而不需要对原数组进行计算,这样可以大大节省计算内存。CamaCoder58 区间和。给定一个数组,输入一个开始索引和结束索引,输出该区间内的数组元素之和。使用前缀和思想就很容易解决。

qq_45465380的博客 234

BMS短路测试避坑指南:从炸管到稳定,我是如何搞定MOS管和TVS的

本文详细记录了BMS短路测试中MOS管和TVS的优化过程,从驱动电阻调整、PCB寄生参数控制到TVS选配策略,提供了一套实用的调试方法论。通过实战案例解析,帮助工程师避免常见陷阱,实现稳定可靠的短路测试性能。

weixin_30652897的博客 140

小红书高时效推荐系统背后的技术升级

在小红书 APP 中,推荐系统的实效性对推荐效果有着特别重要的影响,特别是作为 UGC 平台,小红书的推荐系统如果能更快地捕捉用户与笔记之间的变化和联系,就能够给推荐带来更好的效果。在2021年上半年,首页推荐的召回、粗排、精排的主要模块都保持在天级更新的状态,我们通过持续迭代,将召回 CF 渠道、召回索引更新、召回模型/粗精排模型的训练都做到了分钟级更新,为首页推荐的分发效率带来飞跃式提升,并给业务侧带来非常显著的收益。 小红书站内“最近一天内发布的新笔记”在首页的曝光占比一直很高,这段时间更是快速

REDtech_1024的博客 3528

【基础算法总结】前缀和

前缀和也是基础算法之一,它一般应用于快速求出某个连续区间的和/积。前缀和一般包括一维前缀和,二维前缀和,其实它的做题流程有一点点像动态规划的感觉。前缀和算法的时间复杂度是O(1)。前缀和与二分查找类似,也是有固定模板的,下面的前两题分别就是一维/二维的前缀和模板题。通过上面若干道题目要掌握使用前缀和的两个步骤:一是预处理前缀和数组,这里要先明确 dp[i][j] 的含义,再推导递推公式,二是使用前缀和数组,其实就是在预处理好的 dp 数组中直接拿值,这一步的时间复杂度是O(1)。

2301_77900444的博客 1万+

DAP-Link DIY复刻指南

DAP-Link是ARM开源的一个项目,主要用于代码下载以及调试,支持SWD和JTAG调试接口,对于开发嵌入式的同学相信都或多或少有所耳闻。除了DAP-Link之外还有很多同类型的调试器,如ST-LinkJ-Link,但是这些都是不开源的,无法复刻或进行二次开发。但DAP-Link不同,完全开源,不用担心侵权问题,且随着开源社区大家的共同努力,DAP-Link经过了不断的迭代,先如今已取代ARM之前推出的CMSIS-DAP开源项目。

爱出名的狗腿子 1万+

AcWing 蓝桥杯——手撕前缀和

蓝桥杯java组常用必备知识点之前缀和

m0_57623482的博客 200

设备管理器找不到蓝牙?从驱动到BIOS的系统排查指南

在Windows系统中,蓝牙功能依赖硬件、驱动、系统服务三层协同工作。设备管理器作为硬件状态的可视化窗口,当蓝牙设备消失时,往往意味着某一层链路中断。常见原因包括BIOS无线开关关闭、驱动异常、蓝牙支持服务被禁用,或系统文件损坏。排查思路应从基础概念出发,先理解蓝牙设备在设备管理器中的四种隐藏位置,再通过扫描硬件、检查BIOS、重装驱动、修复服务等步骤逐层定位。这一方法不仅适用于Windows电脑,也适用于HC-05、ESP32等嵌入式蓝牙模块,因为硬件、协议栈、应用层的故障逻辑相通。掌握这套技术价值在于减

weixin_33377602的博客 268

指纹对抗指南:如何绕过Cloudflare与Akamai的5s盾与浏览器指纹检测

现在的CDN反爬技术虽然越来越强,但是道高一尺魔高一丈,只要掌握了指纹伪造、流量伪装、行为模拟这些核心技术,就可以绕过绝大多数的防护措施。对抗过程中要注意效率和成本的平衡,小规模爬取用Playwright+stealth最方便,大规模爬取用curl_cffi+代理池性价比最高,遇到验证码用打码平台或者自动识别服务,不需要死磕破解。本文介绍的方案已经在实战中验证过,可以绕过95%以上的Cloudflare/Akamai防护,成功率非常高。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 299

前缀和与树状数组(手撕算法篇)

我们了解了传统的前缀和数组的优缺点以及树状数组解决了传统前缀和数组的那些问题,也了解了差分数组与前缀和数组之间的关系,接下来就通过几道算法题来提升巩固一下这些知识吧。

u010651383的专栏 369

十.镜头知识之畸变问题

对于理想光学系统,在一对共轭的物像平面上,像的放大率是一个常数。但是对于实际的光学系统,当视场较大或很大时,像的放大率就要随视场而异,这样就会使像相对于物体失去相似性。这种使像变形的成像缺陷称为畸变。

AIoT深度探索者 | 嵌入式系统架构师 深耕物联网(IoT)与人工智能(AI)融合技术,聚焦​​边缘计算、图像开发、低功耗通信协议​​,致力于智能硬件,关注我获取最新技术文章信息与海量资源~ 2126

前缀和——(2)二维数组前缀和

前面部分我们介绍了一维前缀和https://blog.youkuaiyun.com/justidle/article/details/103524440。下面我们扩展一下,来介绍二维前缀和。 什么是二维前缀和 比如我们有这样一个矩阵a,如下所示: 1 2 4 3 5 1 2 4 6 3 5 9 我们定义一个矩阵sum,其中,那么这个矩阵就是这样的: 1 3 7 10 6 9 15 22...

努力中的老周的专栏 2万+

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

前缀和——(1)什么是前缀和和一维前缀和

什么是前缀和 前缀和(Prefix Sum)的定义为:对于一个给定的数列 A, 它的前缀和数列 S 是通过递推能求出来得 部分和。 例如: C++实现 //假设数组a和前缀和数组s都已经定义 int i; //初始条件 a[0] = 0; s[0] = 0; for (i=1; i<=n; i++) { cin >> a[i]; s[i] = s...

努力中的老周的专栏 2万+

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

字节跳动2025年校招笔试手撕真题教程(二)

小基有一个数组,他想知道有多少连续子数组的和同时是 3 和 5 的倍数,但不是 4 的倍数。 输入描述 第一行输入一个整数 n(1≤n≤105)n(1\le n\le 10^5)n(1≤n≤105) 表示数组长度。 第二行输入 nnn 个整数表示数组 ai(1≤ai≤109)a_i(1\le a_i\le 10^9)ai​(1≤ai​≤109)。

大摆王的博客 533

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

上一篇: 面试知识点二
下一篇: 图论bfs与dfs之网络延迟时间
黑猫爱小鹿
博客等级 码龄8年 1万+粉丝 205原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值