一道经典的动态规划问题:最大和子矩阵
有一个正整数和负整数组成的NxN矩阵,请编写代码找出元素总和最大的子矩阵。请尝试使用一个高效算法。
给定一个int矩阵mat和矩阵的阶数n,请返回元素总和最大的子矩阵的元素之和。保证元素绝对值小于等于100000,且矩阵阶数小于等于200。
测试样例:
[[1,2,-3],[3,4,-5],[-5,-6,-7]],3
返回:10
思路: 将二维的矩阵最大和子矩阵转化为一维数组最大和子数组的问题。怎么转化呢?假设输入数组为mat[][],首先在mat[0]中求解出最大和子数组,然后将mat[1]加到mat[0],继续求解最大和子数组,一直到n.当然也要比较从mat[1]起始的最大和子数组,因为我们不能保证mat[0]求解了最大和子数组后和mat[1]相加之后求解最大和子数组的和比直接求解mat[1]的最大和子数组大,同样也要对mat[2]…..mat[n - 1]做同样操作。
//package com.nowcoder.CodingCrack.SubMatrix;
import java.util.*;
public class SubMatrix {
public int sumOfSubMatrix(int[][] mat, int n) {
if (mat == null)
return 0;
int resMax = maxSumArr(mat[0]);
for (int i = 0;i < n;i++)
{
int tempArr [] = mat[i];
resMax = Math.max(resMax, maxSumArr(mat[i]));
for (int j = i + 1;j < n;j++)
{
for (int k = 0;k < mat[0].length;k++)
{
tempArr[k] += mat[j][k];
}
int tempSum = maxSumArr(tempArr);
resMax = Math.max(resMax,tempSum);
}
}
return resMax;
// write code here
}
public int maxSumArr(int [] array)
{
int temp = array[0];
int maxValue = temp;
for (int i = 1;i < array.length;i++)
{
temp = Math.max(array[i], temp + array[i]);
maxValue = Math.max(temp, maxValue);
}
return Math.max(maxValue,temp);
}
}