矩阵 若干问题

来源:互联网 发布:python 幂律分布 编辑:程序博客网 时间:2024/05/22 11:30

将问题先分解到1维数组的情况,即求一维数组的子数组的最大和

对于这个算法原型:维护一个从0开始累加的cur的变量,每当cur的值为负数,就把cur清零继续累加

其基本的原理是最优的结果的任意前缀数组的和一定不会小于0,因为如果小于0的话,把这个前缀丢掉不就可以获得一个更大的和了吗?


回到原题目,现在就是要把二维数组转化为1维的情况,那我们就遍历矩阵的上下边界或者左右边界,然后把这个边界内的累加为一个1维数组就OK了,复杂度O(N^3)





同样是先映射为1维情况下的算法原型:一维数组的子数组累加和小于K的最长长度

这个算法原型的思路是:做一个running sum,到index为i位置时,求前面第一个大于runningSum[i]-K的数的index j_first,然后i-j_first就是必须以i位置上的数结尾的最长长度。

j_first可以用TreeMap,也可以用二分,用二分的话需要把数组处理成非递减的形式,比如:


注意到我们能这样处理是因为:反正只要找到第一个比某个数大的位置,所以当i+1位置的数比i位置的数小时,是可以把i+1位置上的数设为i位置上的数,因为反正有i位置,i+1位置肯定不会有机会

有了这个算法原型,类似二维映射一维也可以放到这个题目







也是把二维映射到1维:遍历矩阵的每一个行,求必须以第i行结尾对应的直方图的最大矩形面积,用的是单调栈(这个算法原型是单调栈的典型运用)

先来看算法原型


然后我们继续进行:


需要说明的是:

(1)结算时要一直结算到栈顶元素大于(小于)要加入的值或者栈为空,然后再把要加入的值压栈

(2)当一个数A从栈里面弹出的时候,当前要加入的数一定是A右边距离A最近的比A大(小)的数,

A弹出后栈顶元素一定是A左边距离A最近的比A大(小)的数

(3)当没有要加入的数时,就认为右边为null,再看左边



有了这个算法原型,怎么把原问题转化为这个算法原型呢?

设我们想要转化的一维数组为a[], 当以第i行结尾时,在第i...0行第j列上从下往上连续的1的个数为K,则a[j]=K

比如:

1 1 0 0 1

1 0 1 0 0

.........

当以第2行结尾时,a = [2 0 1 0 0]


可见,整个复杂度N*M

原创粉丝点击