前缀和/差分
前缀和数组
注意的点 为了省去边界判断,前缀和数组
多开辟一个
从1到n
class PrefixSum { |
一维数组中的前缀和
303. 区域和检索 - 数组不可变
给定一个整数数组 nums
,处理以下类型的多个查询:
- 计算索引
left
和right
(包含left
和right
)之间的nums
元素的 和 ,其中left <= right
实现 NumArray
类:
NumArray(int[] nums)
使用数组nums
初始化对象int sumRange(int i, int j)
返回数组nums
中索引left
和right
之间的元素的 总和 ,包含left
和right
两点(也就是nums[left] + nums[left + 1] + ... + nums[right]
)
示例 1:
输入: |
代码
class NumArray { |
724. 寻找数组的中心下标
难度简单403收藏分享切换为英文接收动态反馈
给你一个整数数组 nums
,请计算数组的 中心下标 。
数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。
如果中心下标位于数组最左端,那么左侧数之和视为 0
,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。
如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1
。
示例 1:
输入:nums = [1, 7, 3, 6, 5, 6] |
暴力超时
class Solution { |
前缀和
class Solution { |
1352. 最后 K 个数的乘积
难度中等73
请你实现一个「数字乘积类」ProductOfNumbers
,要求支持下述两种方法:
1. add(int num)
- 将数字
num
添加到当前数字列表的最后面。
2. getProduct(int k)
- 返回当前数字列表中,最后
k
个数字的乘积。 - 你可以假设当前列表中始终 至少 包含
k
个数字。
题目数据保证:任何时候,任一连续数字序列的乘积都在 32-bit 整数范围内,不会溢出。
示例:
输入: |
前缀积
主要是0的影响 有0的话重新开始前缀
class ProductOfNumbers { |
二维数组中的前缀和
304. 二维区域和检索 - 矩阵不可变
给定一个二维矩阵 matrix
,以下类型的多个请求:
- 计算其子矩形范围内元素的总和,该子矩阵的 左上角 为
(row1, col1)
,右下角 为(row2, col2)
。
实现 NumMatrix
类:
NumMatrix(int[][] matrix)
给定整数矩阵matrix
进行初始化int sumRegion(int row1, int col1, int row2, int col2)
返回 左上角(row1, col1)
、右下角(row2, col2)
所描述的子矩阵的元素 总和 。
示例 1:
输入: |
代码
//笨比前缀和 |
前缀和优化
560. 和为 K 的子数组
给你一个整数数组 nums
和一个整数 k
,请你统计并返回该数组中和为 k
的连续子数组的个数。
示例 1:
输入:nums = [1,1,1], k = 2 |
示例 2:
输入:nums = [1,2,3], k = 3 |
思路

补充修正:最后一条正确路径应该是3-4-5-6-7
个人理解本质上还是前缀和数组presum[i]与presum[j]的差值双重遍历的优化
重点在于哈希的初始化
比如说 从0到某个索引i的前缀和 就是k 也就是从头开始到i的连续子数组和presum[i]就是k,这个时候presum - k 就等于0了,提前把0放一个val = 1就可以统计这个情况了
当出现前缀和等于k的时候会把这段算到答案里,不然hashmap[0]默认为0,就会少一个解
比如1 2 1 target = 2 就不会少
而1 1 1 target = 2 会少一个 情况为前两个1
代码
//笨比的前缀和用法 |
剑指 Offer II 011. 0 和 1 个数相同的子数组
难度中等54
给定一个二进制数组 nums
, 找到含有相同数量的 0
和 1
的最长连续子数组,并返回该子数组的长度。
示例 1:
输入: nums = [0,1] |
示例 2:
输入: nums = [0,1,0] |
思路
- 将数组中的0换成-1, 求和为0的最长子数组 转换成前缀和问题
- 注意!处理0位置
代码
class Solution { |
差分数组
差分数组的主要适用场景是频繁对原始数组的某个区间的元素进行增减。
// 差分数组工具类 |
370. 区间加法

可以直接用刚才的套路解决
vector<int> getModifiedArray(int length, vector<vector<int>> updates) { |
1109. 航班预订统计
这里有 n
个航班,它们分别从 1
到 n
进行编号。
有一份航班预订表 bookings
,表中第 i
条预订记录 bookings[i] = [firsti, lasti, seatsi]
意味着在从 firsti
到 lasti
(包含 firsti
和 lasti
)的 每个航班 上预订了 seatsi
个座位。
请你返回一个长度为 n
的数组 answer
,里面的元素是每个航班预定的座位总数。
示例 1:
输入:bookings = [[1,2,10],[2,3,20],[2,5,25]], n = 5 |
class Solution { |
1094. 拼车
假设你是一位顺风车司机,车上最初有 capacity
个空座位可以用来载客。由于道路的限制,车 只能 向一个方向行驶(也就是说,不允许掉头或改变方向,你可以将其想象为一个向量)。
这儿有一份乘客行程计划表 trips[][]
,其中 trips[i] = [num_passengers, start_location, end_location]
包含了第 i
组乘客的行程信息:
- 必须接送的乘客数量;
- 乘客的上车地点;
- 以及乘客的下车地点。
这些给出的地点位置是从你的 初始 出发位置向前行驶到这些地点所需的距离(它们一定在你的行驶方向上)。
请你根据给出的行程计划表和车子的座位数,来判断你的车是否可以顺利完成接送所有乘客的任务(当且仅当你可以在所有给定的行程中接送所有乘客时,返回 true
,否则请返回 false
)。
示例 1:
输入:trips = [[2,1,5],[3,3,7]], capacity = 4 |
示例 2:
输入:trips = [[2,1,5],[3,3,7]], capacity = 5 |
class Solution { |