小而美的算法技巧:差分数组 :: labuladong的算法小抄 #1004
Replies: 50 comments 3 replies
-
|
Beta Was this translation helpful? Give feedback.
-
倒霉了,一遍没看懂/(ㄒoㄒ)/~~ |
Beta Was this translation helpful? Give feedback.
-
0 <= trips[i][1] < trips[i][2] <= 1000 |
Beta Was this translation helpful? Give feedback.
-
@lumaster 感谢指出,文中写错了,我改下 |
Beta Was this translation helpful? Give feedback.
-
多看几遍 上手敲一敲 (自己敲) 理解逻辑 加油! |
Beta Was this translation helpful? Give feedback.
-
好啊,还能刷到收费的题目,赚了赚了,我说我在lc插件和力扣翻了一会儿没看到这题 |
Beta Was this translation helpful? Give feedback.
-
佩服这些设计者的脑子,我可能一辈子都想不到这么秒的方法。 |
Beta Was this translation helpful? Give feedback.
-
这里的原数组 |
Beta Was this translation helpful? Give feedback.
-
打卡1 |
Beta Was this translation helpful? Give feedback.
-
如果trips = [[9,0,1]], capacity = 4 |
Beta Was this translation helpful? Give feedback.
-
@jay-zhu 可以,但也不是必须的,最后那个 for 循环会统一检查。 |
Beta Was this translation helpful? Give feedback.
-
有点懵 |
Beta Was this translation helpful? Give feedback.
-
看到最多1001的时候震惊了,我竟然用双循环找最大值 |
Beta Was this translation helpful? Give feedback.
-
区间 但是差分数组 一起增大的 差分数组中间不变 只是差分数组的第一个和最后一个 这两个元素不同
|
Beta Was this translation helpful? Give feedback.
-
这里是不是应该注释一下,nums[i] 表示 站点 i 到站点 i+1 之间的乘客人数。由此,虽然有1001个站点,但是 nums 的长度只要 1000 就可以了。 |
Beta Was this translation helpful? Give feedback.
-
发现原来差分数组的前缀和就是原数组!! 其实区间问题可以不用-1,因为你在vec[ 2 ]-1之后 又在后面修改判断 j+1 是不是越界,然后又让 j+1 |
Beta Was this translation helpful? Give feedback.
-
打卡d5 |
Beta Was this translation helpful? Give feedback.
-
1109题我感觉你说的还是挺明白的,但是1094拼车那道题 |
Beta Was this translation helpful? Give feedback.
-
打卡,附上详细代码//拼车的代码
//定义的一个差分数组类,这个类里面主要包括两个主要的方法,一个是更新数组中一个范围的数,另一个方法是返回更新后的数组的结果
class Difference {
//差分数组
private int[] diff;
public Difference(int[] nums) {
int n=nums.length;
if(n<=0){
return;
}
//构造差分数组
diff=new int[n];
diff[0]=nums[0];
for (int i = 1; i <n ; i++) {
diff[i]=nums[i]-nums[i-1];
}
}
//在i-j这个范围内,对数据进行val更新操作,val可以是负值
public void incr(int i,int j,int val){
diff[i]+=val;
//如果j+1超过了数组的范围说明我们是对i到最后的位置进行了更新,所以j后面的就不需要再减val了
if(j+1<diff.length){
diff[j+1]-=val;
}
}
//返回更新后的数组
public int[] result(){
int[] res=new int[diff.length];
res[0]=diff[0];
for (int i = 1; i < diff.length ; i++) {
res[i]=res[i-1]+diff[i];
}
return res;
}
}
public boolean carPooling(int[][] trips, int capacity) {
int[] nums=new int[1001];
Difference difference=new Difference(nums);
for (int[] trip : trips) {
int i=trip[1];
//这里为什么减一,因为到了j位置的时候旅客就下车了
int j=trip[2]-1;
//上车的人数
int val=trip[0];
difference.incr(i,j,val);
}
int[] result = difference.result();
for (int i = 0; i < result.length; i++) {
//我们必须保证在开车的整个过程中,车上的人数不能超过最大载客量也就是capacity
if(result[i]>capacity){
return false;
}
}
return true;
}
//=========================飞机的代码
//定义的一个差分数组类,这个类里面主要包括两个主要的方法,一个是更新数组中一个范围的数,另一个方法是返回更新后的数组的结果
class Difference {
//差分数组
private int[] diff;
public Difference(int[] nums) {
int n=nums.length;
if(n<=0){
return;
}
//构造差分数组
diff=new int[n];
diff[0]=nums[0];
for (int i = 1; i <n ; i++) {
diff[i]=nums[i]-nums[i-1];
}
}
//在i-j这个范围内,对数据进行val更新操作,val可以是负值
public void incr(int i,int j,int val){
diff[i]+=val;
if(j+1<diff.length){
diff[j+1]-=val;
}
}
//返回更新后的数组
public int[] result(){
int[] res=new int[diff.length];
res[0]=diff[0];
for (int i = 1; i < diff.length ; i++) {
res[i]=res[i-1]+diff[i];
}
return res;
}
}
public int[] corpFlightBookings(int[][] bookings, int n) {
int[] nums=new int[n];
Difference difference=new Difference(nums);
for (int[] booking : bookings) {
//题目中描述下标从1开始,因为数组下标从0开始,所以我们要减1
int i=booking[0]-1;
int j=booking[1]-1;
int val=booking[2];
difference.incr(i,j,val);
}
return difference.result();
} |
Beta Was this translation helpful? Give feedback.
-
拼车最后遍历长度为1001的result,其实后边有很多都是0,加一个全局变量记录一下最后下车位置,就不用遍历所有车站了,代码如下
|
Beta Was this translation helpful? Give feedback.
-
1094.拼车 python打卡 class Solution:
def carPooling(self, trips: List[List[int]], capacity: int) -> bool:
nums=[0]*1001
df=Difference(nums)
for trip in trips:
num=trip[0]
start=trip[1]
end=trip[2]-1
df.increment(start,end,num)
res=df.result()
for r in res:
if r>capacity:
return False
return True
class Difference():
def __init__(self,nums:List[int]):
self.nums=nums
self.diff=[0]*len(nums)
self.diff[0]=nums[0]
for i in range(1,len(nums)):
self.diff[i]=nums[i]-nums[i-1]
def increment(self,i,j,val):
self.diff[i]+=val
if (j+1)<len(self.diff):
self.diff[j+1]-=val
def result(self):
res=[0]*len(self.diff)
res[0]=self.diff[0]
for i in range(1,len(self.nums)):
res[i]=res[i-1]+self.diff[i]
return res |
Beta Was this translation helpful? Give feedback.
-
1109.航班预定统计 python打卡
|
Beta Was this translation helpful? Give feedback.
-
diff = [0] * len(nums)
# 构造差分数组
diff[0] = nums[0]
for i in range(1, len(nums)):
diff[i] = nums[i] - nums[i - 1]
# 从这里可以直接反推出得到原始数组的等式
# nums[i] = diff[i] + nums[i-1] 由等式
|
Beta Was this translation helpful? Give feedback.
-
对于各类「区间求和」问题(加粗字体为最佳方案): 数组不变,区间查询:前缀和、树状数组、线段树; 对于各类「区间求和」问题,该用什么方式进行求解,之前在 这里 提到过。 |
Beta Was this translation helpful? Give feedback.
-
计算累加和大佬写错了吧: // 计算 nums 的累加和 应该是下面这样写吧, 要不然preSum数组没有填满 |
Beta Was this translation helpful? Give feedback.
-
注意点:飞机那道题的下标是从1开始的,大巴车的下标是从0开始的! |
Beta Was this translation helpful? Give feedback.
-
拼车内存优化 其实可以先遍历一遍trips找到测试用例中最大的toi,构造长度为最大toi+1的数组,因为最大toi之后车子是空载的。 虽然多遍历了一遍trips,但后续“判断每公里是否超载”的时候,数组长度小了>遍历次数少了,时间也会适当地减少。 |
Beta Was this translation helpful? Give feedback.
-
当 j+1 >= diff.length 时,说明是对 nums[i] 及以后的整个数组都进行修改,那么就不需要再给 diff 数组减 val 了。请问这句话怎么理解不太懂 |
Beta Was this translation helpful? Give feedback.
-
可以计算出最大的下客车站,len就用最大的下客车+1.这样可以节省空间,时间反而更快 |
Beta Was this translation helpful? Give feedback.
-
为啥文章代码里面创建df对象时候只传递了一个参数? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
文章链接点这里:小而美的算法技巧:差分数组
评论礼仪 见这里,违者直接拉黑。
Beta Was this translation helpful? Give feedback.
All reactions