基础算法模板目录汇总(很全!!)
作者:互联网
基础算法模板
题目来自Acwing 网站,该专栏为博主在ACWing算法基础课上的学习记录和总结。
排序
二分和前缀和
二分
求红色部分的右边界
int l = 0, r = n-1;
while(l < r ){
int mid = l + r + 1 >>1;
if(check(红色性质是否满足)) l =mid;
else r = mid -1;
}
这里mid之所以要加上1,是当区间长度为2时,分区一直没有变化,陷入递归死循环。
比如l = r - 1时, mid = (r - 1 + r)/2 = r - 1,如果此时刚好满足红色性质,那么mid会始终等于r - 1,分区一直没有变化,陷入递归死循环。
而加了1之后变成上取整 mid = r,就有机会break掉了。
求绿色部分的左边界
int l = 0, r = n-1;
while(l > r){
int mid = l + r >> 1;
if(check(绿色性质是否满足)) r = mid;
else l = mid + 1;
}
前缀和
一维前缀和
S[i] = a[1] + a[2] + … a[i]
a[l] + … + a[r] = S[r] - S[l - 1] = S[r]-S[l]+a[l]
二维前缀和
S[i, j] = 第i行j列格子左上部分所有元素的和
以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵的和为:
S[x2, y2] - S[x1 - 1, y2] - S[x2, y1 - 1] + S[x1 - 1, y1 - 1]
差分
一维差分
给区间[l, r]中的每个数加上c:B[l] += c, B[r + 1] -= c
对于数组a[i] = b[1] + b[2 ]+ b[3] +…… + b[i]
则a数组是b数组的前缀和数组,b数组叫做a数组的差分数组。差分数组为:
b[0] = a[0 ]= 0;
b[1] = a[1] - a[0];
b[2] = a[2] - a[1];
b[3] =a [3] - a[2];
…
b[n] = a[n] - a[n-1];
有了差分数组b,通过前缀和运算,就可以在O(n) 的时间内得到a数组。给定数组a,对a数组[l,r]区间中的每一个数加上c,常规做法是循环l到r加上c。执行m次操作,时间复杂度就为O(n*m)。
对于这个问题,就可以使用差分数组了:
给a数组中的[ l, r]区间中的每一个数都加上c,只需对差分数组b做 b[l] + = c, b[r+1] - = c。时间复杂度为O(1)。
二维差分
给以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵中的所有元素加上c:
S[x1, y1] += c, S[x2 + 1, y1] -= c, S[x1, y2 + 1] -= c, S[x2 + 1, y2 + 1] += c
双指针算法
使用双指针算法可以将常规的双重循环O(n^2)复杂度,根据题目给的某种性质优化为O(n)。虽然是双重for循环,但是扫描的次数不超过
O(2n)。
for(int i = 0, j =0; i < n; i++){
while(j <= i&& check(j,i) )j++;
题目逻辑处理代码;
}
标签:算法,前缀,汇总,mid,差分,很全,数组,y1,模板 来源: https://blog.csdn.net/weixin_44855907/article/details/112797290