前缀和与尺取法学习收获
关于前缀和:
在做题的时候我们会经常的遇到一组数据,数据个数会比较大题目又要求需要对数组的区间进行处理,这时候若是对数组进行遍历的话那么对时间的花费将是巨大的,为了能够减少时间的花费就可以考虑对所给的区域端点进行处理而替代对区域间所有元素的处理。
举个栗子:
给定一组数据,求其中的宽度为k的区域之间的所有元素之和。
例如 1,5,8,9,1,2,4,3,4,1,0,1,1,2,5
求宽度为3的区域的元素和最大为多少;
这时候很容易想到的是一个for循环从第一个开始遍历,但是我能不能有更好一点的方法呢?当然有,就是前缀和!
我们令一个数组a,a[0]=0,从a[1]开始存入数据,在存入数据时令a[i]+=a[i-1];那么存入后的数组就是这样的
0,1,6,14,23,24,26,30,33,37,38,38,39,40,42,47;
如果我们需要求第一个到第三个之间的元素之和就可以用a[3]-a[1-1];因为端点也是要加进去的,所以
需要减去前端端点的前一个,那么就得到答案了。这样的话在遍历中就会少很多的不必要操作,节省很多的时间,前缀和也是可以拓展到二维的,二维的前缀和在矩阵之中的应用是非常妙的;
二维前缀和可以看看牛客上的几道题;
激光炸弹
[土]秘法地震//写写题就能理解了
关于尺取法(好像也有人叫做双指针,不过我并没有用到指针);
尺取的用处也非常的大,emmmmmmm为了方便理解我就再举个栗子,
例如 1,1,1,2,1,4,5,2,3,1,1,1,2,1,1,1,1,1
我们在这组数据中求和为5的最短区间;
我们令l=0,r=0;l就是left缩写的意思,r为right缩写的意思;
l保持为0,r往右移动当和等于5的时候记录l与r之间元素个数,l往左移如果依然满足条件就更新个数否则就将r再右移动直到符合条件,在记录个数,比较,小的话就更新否则就不更新,以此类推直到l(left)到最右边;
这个的应用也是很灵活的可以参考题目
subsequence
//题目均可在牛客上找到