给出一个 m*n 的二维数组(元素可为正可为负),求该二维数组的一个子数组,且此子数组中所有元素的和最大,并输出该数组的和。

给出一个 m*n 的二维数组(元素可为正可为负),求该二维数组的一个子数组,且此子数组中所有元素的和最大,并输出该数组的和

——刘铸辉    何晓楠

 

思路:

先枚举子数组再将其压缩成一维数组求其值并比较出最大值输出

方法:

 若从第i行开始,到第j行结束的数组中子数组的最大和

为了求 我们对这个数组(第i行开始,到第j行结束的数组)进行处理:

(1)把这个数组中的每一列数相加,最后形成一个一维数组,其长度等于原二维数组列的个数。

(2)在该一维数组上,求解最大子数组和。

 这是从网上找的 不是自己写的 ,不过感觉这个程序还行,不过在压缩时每列相加的一维数组有点浪费时间,所以优化了一下: 在 给出一个二维子矩阵后,为了更快地求出其对应的一维矩阵, 使用二维数组sum[x][y]预先保存第y列,从第0行到第x行之间元素之和。这样他的时间复杂度就减少了,花的时间少了。 原来的时间复杂度O((m*n)^2),

现在的时间复杂度为O(m*m*n)。这里就直接给出优化后的代码大家:可以看下

把原矩阵第i行和第j行之间元素进行压缩,形成一个一维数组

 

void InitSumArr(int** pnArr,int** pnArrColSum,int nXLen,int nYLen)
{
    assert(pnArr && *pnArr && pnArrColSum && *pnArrColSum);
    assert(nXLen > 0 && nYLen > 0);
    for (int i = 0;i < nXLen;i++)//横坐标
    {
        for (int j = 0;j < nYLen;j++)//纵坐标
        {
            pnArrColSum[i][j] = 0;
            for (int t = 0;t <= i;t++)
            {
                pnArrColSum[i][j] += pnArr[t][j];
            }
        }
    }
}
View Code

枚举二维数组,压缩成一维数组,求解最大子数组和

 

int MaxSubMatrixSum(int** pnArr,int** pnArrColSum,int nXLen,int nYLen)
{
    assert(pnArr && *pnArr && pnArrColSum && *pnArrColSum);
    assert(nXLen > 0 && nYLen > 0);
    int nMaxSum = -0x3f3f3f3f;
    int nCurSum = -0x3f3f3f3f;
    int* pTmpArr = new int[nYLen]; 
    for (int i = 0;i < nXLen;i++)
    {
        for (int j = i;j < nXLen;j++)
        {
            if (i == 0)
            {
                for (int t = 0;t < nYLen;t++)
                {
                    pTmpArr[t] = pnArrColSum[j][t];
                }
                nCurSum = MaxSubSum(pTmpArr,nYLen);
                nMaxSum = max(nCurSum,nMaxSum);
            }
            else
            {
                //计算每列元素和,并求最大子数组之和
                for (int t = 0;t < nYLen;t++)
                {
                    pTmpArr[t] = pnArrColSum[j][t] - pnArrColSum[i - 1][t];
                }
                nCurSum = MaxSubSum(pTmpArr,nYLen);
                nMaxSum = max(nCurSum,nMaxSum);
            }
        }
    }
    return nMaxSum;
}
View Code

    虽然这不是我们自己写的,但我和辉哥也学会了二维数组如何寻找最大子数组,一开始也没想到,嘿嘿 ,惭愧啊,不过这次记住了,还是有收获的。

  

  

 

posted @ 2014-03-19 20:26  何晓楠  阅读(1204)  评论(1编辑  收藏  举报