代码题(35)— 最大和子矩阵

1、最大和子矩阵

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

  假定原始矩阵的行数为M,那么对于子矩阵,它的行数可以是1到M的任何一个数,而且,对于一个K行(K < M)的子矩阵,它的第一行可以是原始矩阵的第1行到 M - K + 1 的任意一行。同时对于每一个得到的子矩阵,假设这个子矩阵是 2 *k, 也就是说它只有两行,要找出最大子矩阵,我们要从左到右不断的遍历才能找出在这种情况下的最大子矩阵。如果我们把这两行上下相加,情况就和求“最大子段和问题” 又是一样的了。

  为了找出在原始矩阵里的最大子矩阵,我们要遍历所有的子矩阵的可能情况,也就是说,我们要考虑这个子矩阵有可能只有1行,2行,。。。到n行。而在每一种情况下,我们都要把它所对应的矩阵部分上下相加才求最大子矩阵(局部)。

class SubMatrix {
public:
    int sumOfSubMatrix(vector<vector<int> > mat, int n) {
        // write code here
        if(mat.empty() || n<=0)
            return 0;
        int maxsum = 0;
        for(int i=0;i<n;++i)
        {
            vector<int> temp(mat[i]);
            maxsum = max(maxsum, subArray(temp));
            for(int j=i+1;j<n;++j)
            {
                for(int k=0;k<n;++k)
                {
                    temp[k] = temp[k] + mat[j][k];
                }
                maxsum = max(maxsum, subArray(temp));
            }
        }
        return maxsum;
    }
    // 一维数组最大自序和
    int subArray(vector<int> &temp)
    {
        int sum = temp[0];
        int maxsum = temp[0];
        for(int i=1;i<temp.size();++i)
        {
            if( sum>=0)
                sum += temp[i];
            else
                sum = temp[i];
            maxsum = max(maxsum, sum);
        }
        return maxsum;
    }
};
原文地址:https://www.cnblogs.com/eilearn/p/9424998.html