最大子矩阵和

最大子矩阵和

感谢前人的总结
参考链接1
参考链接2

因为觉得参考链接讲解依然不够清楚,所以写了这篇博客。

好吧其实是因为今天面试了这道题,自己想了很久没想出来所以想写一下。

啊 求offer

问题重述

求一个n x n的矩阵 M 的最大子矩阵和。
比如在如下这个矩阵中:
 0 -2 -7  0
 9  2 -6  2
-4  1 -4  1
-1  8  0 -2 
拥有最大和的子矩阵为:
 9 2
-4 1
-1 8
其和为15

解答

这里只讲O(n3)的解法,也就是最优解。暴力解实在没有讲解的必要。

一维的解决方案

首先要简化问题。考虑一维的情况,这就是一个“最大子段和问题”,有O(n)的解法,具体自己去查。

将二维问题分解

假设最大和子矩阵的行数为R,R∈[1,n]。

子问题:对矩阵M所有行数为R的子矩阵,它们的最大和是多少。答案记为SR

显然 MAX(S1,S2……,Sn 即为本题的答案。

子问题求解

子问题:对矩阵M所有行数为R的子矩阵,它们的最大和是多少。

对任意行数为R的子矩阵,矩阵M中必然存在一个连续的R行包含该子矩阵。

我们从M中任取连续的R行作为“条状矩阵”,有n-R+1中取法。

假设R=2,则从M中任取连续的2行作为“条状矩阵”,有n-1种取法。

条状矩阵的维度为R X n。

R=2时条状矩阵的维度为2 X n。

孙问题:对每一个(共n-R+1个)条状矩阵,求其R行子矩阵最大的矩阵和。

对得到的n-R+1个最大矩阵和求最大值,得到矩阵M的R行子矩阵最大矩阵和,即子问题答案。

孙问题求解

孙问题:对每一个(共n-R+1个)条状矩阵,求其R行子矩阵最大的矩阵和。

条状矩阵的维度为R X n,我们要求R行子矩阵,注意到两者的行维度是一样的,都是R行。

也就是说,我们只需要考虑子矩阵是从条状矩阵的第几列到第几列,不必考虑行,因为行维度相同,一旦列数确定,该列所有的行都在子矩阵中。

对条状矩阵同一列的所有元素而言,他们要么都在子矩阵中,要么都不在子矩阵中,不可能分离。

因此我们将同一列元素都相加,他们的和组成一个一维数组,对这个数组求“最大子段和问题”就得到了孙问题的解答。

时间复杂度分析和实现

总时间复杂度O(n3)

R=1时有n个条状矩阵,R=2时有n-1个条状矩阵……总共有
∑ 1 n 1 = ( 1 + n ) n / 2 \sum_1^n 1 = (1+n)n/2 1n1=(1+n)n/2
个条状矩阵。
对每一个条状矩阵,求解孙问题的复杂度为 O(n),因此总复杂度为O(n3)。

孙问题的O(n)

孙问题需要优化才能O(n)。

“最大子段和问题”是O(n)的,这没有什么问题。

但是下面这一步(将其称为“劣质步骤”)

同一列元素都相加,他们的和组成一个一维数组

复杂度是O(R*n),这会使我们的时间复杂度恶化,我们要优化。

建立一个与M相同维度的矩阵J,其中元素J[x][y]代表M第y列前x行的和。

劣质步骤中的求和不再一个一个加,而是用该列的前k项和减去前h-1项和就得到了该列第h到k项的和。

这样,劣质步骤中的求和操作就可以O(1)地完成,劣质步骤总时间复杂度优化为O(n)。

例如,对R=3的一个条形矩阵

 9  2 -6  2
-4  1 -4  1
-1  8  0 -2 

它是M矩阵中的第2、3、4行,我们优化过的求和可以使用如下代码

for(int i=0;i<n;i++){
    res[i]=J[4][i]-J[1][i];
}

建立矩阵J的时间为O(n2),因为本题算法为O(n3),所以不影响。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值