最大和子矩阵

有一个正整数和负整数组成的NxN矩阵,请编写代码找出元素总和最大的子矩阵。请尝试使用一个高效算法。

给定一个int矩阵mat和矩阵的阶数n,请返回元素总和最大的子矩阵的元素之和。保证元素绝对值小于等于100000,且矩阵阶数小于等于200。

测试样例:
[[1,2,-3],[3,4,-5],[-5,-6,-7]],3
返回:10

思路:

1:先将二维数组纵向合并成一维数组 然后计算一维数组的最大子序列和。

2:最大一维子序列求和问题

例如数组1  2  3 -4  5 -8  7 4  2 -10

定义temp存储0~i位置的累加和

定义Max为0~i位置的最大累加和

temp初始化为0 temp与0比较 若小于零 temp = mat[i] 否则temp=+mat[i];

temp每次变化时都和max比较 若大与max则max=temp 否则 max不变

      i      0   1   2   3   4   5   6   7   8   9

 mat     1   2   3  -4   5  -8   7   4   2  -10

temp    1   3   6   2   7  -1  7  11  13  3

max     1   3   6   6   7   7   7  11 13 13 

最大和为13

思考为什么这样做是对的?

假设一个子数组是我们要找的最大子数组i~j

那么  i<=k<j  i~k必定大与0 如果i~k小于0 那么i~j 必定小于 k~j

因此只要前i个和为正就记录并继续往下累加 即可求出最大累加和

  public int sumOfSubMatrix(int[][] mat, int n) {
       int max = Integer.MIN_VALUE;
        int temp;
        int[] b = new int[n];
        for(int i=0;i<n;i++){
            for(int t=0;t<n;t++){//数据使用过后要清空 防止脏数据
                b[t] = 0;
            }
            for(int j=i;j<n;j++){
                for(int k=0;k<n;k++){//将二维数组 纵向合并成一维数组
                    b[k]+=mat[j][k];
                }
                temp = sumOfSub(b,n);
                if(temp>max){
                    max = temp;
                }
            }
        }
        return max;
    }
    /**一维数组求解子序列最大值问题
     * @param mat
     * @param n
     * @return
     */
    public int sumOfSub(int[] mat,int n){
        int max = Integer.MIN_VALUE;
        int temp = 0;
        for(int i=0;i<n;i++){
            if(temp<0){
                temp = mat[i];
            }else{
                temp+=mat[i];
            }
            if(temp>max){
                max = temp;
            }
        }
        return max;
    }
题目来源:http://www.nowcoder.com/practice/840eee05dccd4ffd8f9433ce8085946b?tpId=8&tqId=11075&rp=5&ru=/ta/cracking-the-coding-interview&qru=/ta/cracking-the-coding-interview/question-ranking

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值