[leetcode-363]Max Sum of Rectangle No Larger Than K(java)
2016-07-03 11:10
393 查看
这道题我的想法就是使用暴力搜索,维护两个节点,第一个节点是矩阵的左上角,第二个节点是矩阵的右下角。然后在围起来的矩阵里面去计算面积。
假设矩阵的行为M,矩阵的列为N,那么上述算法的事件复杂度为O(MN*MN*MN)。因此肯定是不可行的。
于是只能采用用空间换取时间的方法,对于每个节点,将(0,0)看做矩阵的左上角,将当前节点看成矩阵的右下角,记录下当前节点对应的行和宽。
但是很不幸,代码TLE,原因在于,在计算面积时还是要有个for循环。
于是又更新了一般,这一版里面维护了以当前节点为右下角,以(0,0)为左上角的矩阵的面积。OK,通过!
代码1:
更新后:
假设矩阵的行为M,矩阵的列为N,那么上述算法的事件复杂度为O(MN*MN*MN)。因此肯定是不可行的。
于是只能采用用空间换取时间的方法,对于每个节点,将(0,0)看做矩阵的左上角,将当前节点看成矩阵的右下角,记录下当前节点对应的行和宽。
但是很不幸,代码TLE,原因在于,在计算面积时还是要有个for循环。
于是又更新了一般,这一版里面维护了以当前节点为右下角,以(0,0)为左上角的矩阵的面积。OK,通过!
代码1:
public class Solution { class Node{ int totalRow; int totalCol; Node(int rowVal,int colVal){ totalRow = rowVal; totalCol = colVal; } } public int maxSumSubmatrix(int[][] matrix, int k) { int row = matrix.length; int col = matrix[0].length; Node[][] totalMatrix = new Node[row][col]; initTotalMatrix(matrix,totalMatrix); int max = Integer.MIN_VALUE; for(int rowUp = 0;rowUp<row;rowUp++){ for(int colUp = 0;colUp<col;colUp++){ for(int rowDown = rowUp;rowDown<row;rowDown++){ for(int colDown = colUp;colDown<col;colDown++){ int res = getArea(matrix,totalMatrix,rowUp,colUp,rowDown,colDown); if(res <= k){ if(res == k) return res; if(res > max) max = res; } } } } } return max; } private int getArea(int[][] matrix,Node[][] totalMatrix,int upRow,int upCol,int downRow,int downCol){ int col = downCol-upCol; int row = downRow-upRow; int res = 0; if(col < row){ for(int i = upCol;i<=downCol;i++){ res += totalMatrix[downRow][i].totalCol - totalMatrix[upRow][i].totalCol + matrix[upRow][i]; } }else{ for(int i = upRow;i<=downRow;i++){ res += totalMatrix[i][downCol].totalRow - totalMatrix[i][upCol].totalRow + matrix[i][upCol]; } } return res; } private void initTotalMatrix(int[][] matrix,Node[][] totalMatrix){ int row = matrix.length; int col = matrix[0].length; Node tmp; for(int i = 0;i<row;i++){ for(int j = 0;j<col;j++){ tmp = new Node(matrix[i][j],matrix[i][j]); totalMatrix[i][j] = tmp; if(i > 0){ Node prevRowNode = totalMatrix[i-1][j]; tmp.totalCol += prevRowNode.totalCol; } if(j > 0){ Node prevColNode = totalMatrix[i][j-1]; tmp.totalRow += prevColNode.totalRow; } } } } }
更新后:
public class Solution { class AreaNode{ int area; AreaNode(int area){ this.area = area; } } class TotalNode{ int totalRow; int totalCol; TotalNode(int row,int col){ totalRow = row; totalCol = col; } } public int maxSumSubmatrix(int[][] matrix, int k) { int row = matrix.length; int col = matrix[0].length; AreaNode[][] areaMatrix = new AreaNode[row][col];//保存面积信息 TotalNode[][] totalMatrix = new TotalNode[row][col];//保存行列信息 initareaMatrix(matrix,areaMatrix,totalMatrix); int max = Integer.MIN_VALUE; for(int rowUp = 0;rowUp<row;rowUp++){ for(int colUp = 0;colUp<col;colUp++){ for(int rowDown = rowUp;rowDown<row;rowDown++){ for(int colDown = colUp;colDown<col;colDown++){ int res = getArea(areaMatrix,totalMatrix,rowUp,colUp,rowDown,colDown) + matrix[rowUp][colUp]; if(res <= k){ if(res == k) return res; if(res > max) max = res; } } } } } return max; } private int getArea(AreaNode[][] areaMatrix,TotalNode[][] totalMatrix,int upRow,int upCol,int downRow,int downCol){ return areaMatrix[downRow][downCol].area - areaMatrix[upRow][downCol].area - areaMatrix[downRow][upCol].area + areaMatrix[upRow][upCol].area + totalMatrix[upRow][downCol].totalRow - totalMatrix[upRow][upCol].totalRow +totalMatrix[downRow][upCol].totalCol - totalMatrix[upRow][upCol].totalCol; } private void initareaMatrix(int[][] matrix,AreaNode[][] areaMatrix,TotalNode[][] totalMatrix){ int row = matrix.length; int col = matrix[0].length; for(int i = 0;i<row;i++){ for(int j = 0;j<col;j++){ int res = 0; int totalRow = matrix[i][j]; int totalCol = matrix[i][j]; if(i > 0){ res += areaMatrix[i-1][j].area; totalCol += totalMatrix[i-1][j].totalCol; } if(j > 0){ res += areaMatrix[i][j-1].area; totalRow += totalMatrix[i][j-1].totalRow; } if(i > 0&&j > 0){ res -= areaMatrix[i-1][j-1].area; } res += matrix[i][j]; areaMatrix[i][j] = new AreaNode(res); totalMatrix[i][j] = new TotalNode(totalRow,totalCol); } } } }
相关文章推荐
- Javascirpt闭包问题以及解决方案
- Java中==和equals()的区别
- Java 学习笔记
- java框架之springmvc07(国际化处理)
- Struts2校验方法validate以及validateXxx方法
- DAO设计模式
- Thinking in java-对象导论
- Error creating the view. An error occurred while automatically activating bundle
- Error creating the view. An error occurred while automatically activating bundle
- 二叉树的递归和非递归实现 java
- java时间和日期类型
- Java内存机制
- Spring学习(一)—入门
- 【Java进阶一】理解封装
- java 控制台输入的两种方式
- Java内存管理机制
- spring 10 bean配置-通过FactoryBean配置bean
- java 最长回文字串
- 关于java比较器
- 其它常用流对象