学习笔记之最大子矩阵问题
2016-07-13 10:16
232 查看
首先来看看一维的最大字段和问题的解法:
动态规划算法求解
算法思路如下:
记
,则所求的最大子段和为:
由b[j]的定义知,当b[j-1]>0时,b[j]=b[j-1]+a[j],否则b[j]=a[j]。由此可得b[j]的动态规划递推式如下:
b[j]=max{b[j-1]+a[j],a[j]},1<=j<=n。该算法的时间复杂度和空间复杂度都为O(n)。
具体代码如下:
接下来看一下最大子矩阵和问题:
(1)问题描述:给定一个m行n列的整数矩阵A,试求A的一个子矩阵,使其各元素之和为最大。
(2)动态规划法求解:
用二维数组a[1:m][1:n]表示给定的m行n列的整数矩阵。子数组a[i1:i2][j1:j2]表示左上角和右下角行列坐标分别为(i1,j1)和(i2,j2)的子矩阵,其各元素之和记为:
最大子矩阵问题的最优值为
。如果用直接枚举的方法解最大子矩阵和问题,需要O(m^2n^2)时间。注意到
,式中,
,设
,则
容易看出,这正是一维情形的最大子段和问题。因此,借助最大子段和问题的动态规划算法MaxSubArray,可设计出最大子矩阵和动态规划算法如下:
b[k]代表i到j行第k列的值的总和,循环列数,计算出i到j行每一列的总和,得到一维数组b为选定行的列项和,此时对b进行一维数组最大子段和的计算,确定选定列。此时即可求出i到j行子矩阵的最大和。
动态规划算法求解
算法思路如下:
记
,则所求的最大子段和为:
由b[j]的定义知,当b[j-1]>0时,b[j]=b[j-1]+a[j],否则b[j]=a[j]。由此可得b[j]的动态规划递推式如下:
b[j]=max{b[j-1]+a[j],a[j]},1<=j<=n。该算法的时间复杂度和空间复杂度都为O(n)。
具体代码如下:
int maxSubArray(int[] nums){ int length = nums.length; int sum = 0;int max = 0; for(int i = 0;i<length;i++){ if(sum>0) sum+=nums[i]; else sum = nums[i]; if(sum>max) max = sum; } return max; }
接下来看一下最大子矩阵和问题:
(1)问题描述:给定一个m行n列的整数矩阵A,试求A的一个子矩阵,使其各元素之和为最大。
(2)动态规划法求解:
用二维数组a[1:m][1:n]表示给定的m行n列的整数矩阵。子数组a[i1:i2][j1:j2]表示左上角和右下角行列坐标分别为(i1,j1)和(i2,j2)的子矩阵,其各元素之和记为:
最大子矩阵问题的最优值为
。如果用直接枚举的方法解最大子矩阵和问题,需要O(m^2n^2)时间。注意到
,式中,
,设
,则
容易看出,这正是一维情形的最大子段和问题。因此,借助最大子段和问题的动态规划算法MaxSubArray,可设计出最大子矩阵和动态规划算法如下:
public int maxMatrix(int[][]nums){ int rows = nums.length; int cols = nums[0].length; int max = 0; int[] b = new int[cols]; for(int i = 0;i<rows;i++){ for(int k = 0;k<cols;k++) b[k] = 0; for(int j = i;j<rows;j++){ for(int k = 0;k<cols;k++){ b[k] += nums[j][k]; } int sum = maxSubArray(b); if(sum>max) max = sum; } } return max; }
b[k]代表i到j行第k列的值的总和,循环列数,计算出i到j行每一列的总和,得到一维数组b为选定行的列项和,此时对b进行一维数组最大子段和的计算,确定选定列。此时即可求出i到j行子矩阵的最大和。
相关文章推荐
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#递归算法之分而治之策略
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- C#算法之大牛生小牛的问题高效解决方法
- C#算法函数:获取一个字符串中的最大长度的数字
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- 经典排序算法之冒泡排序(Bubble sort)代码
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法