zoukankan      html  css  js  c++  java
  • 给出一个 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

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

      

      

  • 相关阅读:
    Java基础之泛型——使用通配符类型参数(TryWildCard)
    Java基础之泛型——使用二叉树进行排序(TryBinaryTree)
    Java基础之泛型——使用泛型链表类型(TryGenericLinkedList)
    Java基础之序列化对象——反序列化对象(DeserializeObjects)
    Java基础之序列化对象——将对象写入到文件中(SerializeObjects)
    拷贝excel里的内容转为JSON的js代码
    asp.net 正则获取url参数
    vs2013给类添加默认注释
    日货EmEditor的使用小技巧
    express不是内部或外部命令
  • 原文地址:https://www.cnblogs.com/hexiaonan/p/shuzumax.html
Copyright © 2011-2022 走看看