差分、前缀和数组(C语言)

差分、前缀和数组

差分数组

作用:加快区间修改的速度

一般要将数组的[i, j]区间元素都加上或减去一个数,需要从i遍历到j,但是使用差分数组,只需要修改差分数组上两个位置的值即可

int nums[6] = {2, 3, 5, 8, 4, 9};	//待操作的数组
int diff[6];
diff[0] = 0;
for(int i = 1; i < 6; i++){
    diff[i] = nums[i] - nums[i - 1];
	}
//diff[6] = {0, 1, 2, 3, -4, 5};
diff[1] += 1, diff[5] -= 1;	//diff[6] = {0, 2, 2, 3, -4, 4};
nums[0] += diff[0];	//假设nums[0]的前一个元素为0
for(int i = 1; i < 6; i++){
    nums[i] = nums[i - 1] + diff[i];
	}
//nums[6] = {0, 4, 6, 9, 5, 9}; 

如果我们想将区间[1, 4]都加上1,只需要diff[1] + 1,diff[4 + 1] - 1即可,因为diff[1]+1表示,1位置上的数与前一个数的差值增加了1,而2与1的差值仍为2,这就相当于2相当于1前面的数加了1,以此内推可知,如果diff[i] + d,就相当于i及之后的值都加上了d,而要做到[i, j]区间的修改,则需要将diff[j + 1] - d,就相当于反向抵消了。
[i to j] + d = diff[i] + d and diff[j + 1] - d;
恢复:

for(int i = 0; i < numsSize; i++){
	if(i == 0) nums[i] += diff[i];
	else nums[i] = diff[i] + nums[i - 1];
}

前缀和数组

作用:加快区间和的计算

//preSum[i]表示区间[0,i)的元素和
int nums[5] = {1, 3, 5, 7, 9};
int preSum[5 + 1];	//一般是元素个数+1,因为区间是左闭右开的
preSum[0] = 0;
for(int i = 1; i < 5; i++){
    preSum[i] = preSum[i - 1] + nums[i];
	}
//preSum[6] = {0, 1, 4, 9, 16, 25};
//如果要求区间[i, j]的和,只需要计算preSum[j + 1] - preSum[i]的值即可
//即[0, j + 1) 与 [0, i)两个集合的差(补)集
int Sum_1_to_3 = preSum[4] - preSum[1];	//16 - 1 = 3 + 5 + 7 = 15

Sum[i to j] = preSum[j + 1] - preSum[i];

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值