前缀和:sum[i] = 前 i 个数的和
差分:delta[i] = a[i] - a[i-1];在delta[0]的位置上补0
-
校门外的树
第一思路:利用差分数组,对于每个区间,左端点加一,右端点减一,最后统计马路上差分前缀和为0的点数
-
解法1:对于输入的每个区间,区间上的所有数加一,最后统计值为0的点;只适用于小数据范围
-
解法2:差分数组求前缀和
缺点:在数轴上会存在大量差分数组前缀和为0的点,这些树所在区间的值从未发生变化,对其差分数组进行前缀求和本身是无意义的,更好的做法是只需记录有变化的区间即可。
-
解法3:结构体数组记录左右端点;通过把有重复区域的区间合并的方式把大量区间转化成无交集的少量区间,并直接利用区间长度计算结果;具体做法是对所有区间的左区间进行排序,通过比较当前区间的右端点与下个区间的左端点大小来确定有无交集;有交集的话继续合并,无交集的话先减去当前大区间,寻找并逐渐合并得到下一个大区间。
-
解法4:差分数组的改进,运用了离散化的思想;差分数组用结构体数组替换,计算前缀和的时候不必再对差分数组中无意义的点进行加和了
-
-
中位数图
解法:中位数置为0,比中位数大的数记为1,比中位数小的数记为-1;只需求所有数加和为0的奇长度子串个数即可;具体做法是以0为分界点,设置数组分别表示左边的后缀和和右边的前缀和,当右边的前缀和为x的时候,左边的后缀和为-x即可,各统计两边x的值,最后统计个数即可
-
激光炸弹
第一思路:二维前缀和;正方形内的权值加和等于(右上顶点-左上-右下+左下顶点)的权值加和;提前把每个矩形内的权值总和计算出来存储在数组中,矩形的左下角都为原点,右上角为给定的坐标
-
乘客到公交车站最近距离
结论:人数刚刚过半的点是最佳点;用距离公式推导出结论
第一思路:暴力解题
-
解法1:结论解题;数学公式建立相邻两个点之间的距离变化公式,通过单调性找出最小极值点
-
解法2:通过数学公式dist(x+1)=dist(x)+(x之后的人数-x之前的人数)*(dist(x+1)-dist(x));dist(0)暴力得出,后面的dist由数学公式推导得出,最后比较dist找出最小值
-
-
距离平方总和最小(第四题变种)
解法:依然利用公式推导,算出dist(x+1)与dist(x)的公式并相减,分离定量与变量简化运算
-
subsequence:求总和大于S的最短连续子序列
双指针、尺取法、追逐法
第一思路:从左到右依次添加元素进子序列中,当子序列的总和大于S之后,判断新加入的元素是否大于序列最早加入的元素(元素从左到右依次添加进子序列),大于的话就替换,否则的话就从这里重新创造子序列
解法:与第一思路一致,由于新元素的加入与老元素的移除使得子序列看起来像在母序列上移动一样,具体做法中有部分细节不同:不必判断新元素是否大于老元素,这样的话序列会在某一情况下停止移动;而应该判断子序列与S的关系,如果大于左边就一直去掉元素,小于的话就一直添加右边的母序列新元素;同时int len记录长度情况,该做法与第一思路不同之处在于不必保存子序列最后求得到的多个子序列中的最短len值,而是len在子序列移动的过程中就已经记下了最短的len值
-
字符串:包含字符串所有小写字母的子串的最小长度
-
丢手绢:小朋友间最远距离
解法:依然是双指针,距离过半之后就左指针移动,未过半的时候右指针继续移动
-
扫雷
枚举第一个位置有没有雷(总共两种情况),推算其它格子中成不成立即可