习题10求解的是查找数组中总和最接近于0的子数组。
们可以尝试使用“将x[0...n-1]扩展为x[0...n]”的思想,建立一个累积和表cumSum进行处理。这里假设输入数组为x[n],那么则有
由此我们发现,cumSum两个元素的差值恰好对应一个子数组的和。
剩下我们只需要对cumSum进行排序,然后寻找最接近(差值的绝对值最小)的相邻的两个数即可。在cumSum和数组中最接近的相邻两个数表示的就是原来数组x中两个最接近的子数组的和。然后这两个子数组之间的隔着的数的和就是最接近于0的子数组的和。因为两个子数组之间隔着的数的和就是上面cumSum中两个最接近的相邻两个数的差。
如果要求得是最接近于数值t的子数组,那么就不能够采用上面的方法了。不能够采用找cursum相邻数中差值最接近于t的方法来求解。这种思路只适合于最接近于0.因为cursum经过排序后,相邻两数一定是最接近的,也是最有可能接近0的。所以比较相邻两数的差值找一个绝对值最小的就可以了。但如果要求得是最接近于t的,那么很有可能就不是相邻的两数差值最接近了,而有可能是不相邻的两个数的差值的绝对值最接近。对于这种情况采用暴力搜索可能会比较好
习题11
收费站i和j,cursum[j] -cursum[i-1]就表示在i和j内行驶的路段费用,并且只占用 curarr[n]的线性空间。而且这里不需要再对cursum进行排序。
习题13
《编程之美》2.15节。
采用暴力方法,需要遍历每个子数组,并计算和,O(N^4 * SUM). (SUM为计算每个子数组的和的时间).
动态规划的方法。
将二维转化为一维。枚举矩形上下边界,对每一个确定的上下边界,只有左右边界是待定的,类似于一维子数组最大和的方式。