活跃农民
- 积分
- 813
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2014-3-17
- 最后登录
- 1970-1-1
|
本帖最后由 619899442 于 2017-12-7 05:21 编辑
我有一个不成熟的小想法:使用DP实现:
假设DP[j] 代表可以从左上角移动到(i, j) 的最大正方形,那么有三种方式使它移动到(i, j):
1. 无需移动
2. 从左到右
3. 从上到下
但是这样做的复杂度是O(mn), 跟楼主给的不太一样,所以我并不是很确定- public class MaxMoveableRect {
- private static int MaxMoveableRect(int [][] matrix) {
- int m = matrix.length;
- int n = matrix[0].length;
- // allOnes[i][j] == whether the rectangle defined by (0,0) and (i, j) only
- // contains 1
- boolean [][] allOnes = new boolean [m][n];
- allOnes[0][0] = (matrix[0][0] == 1) ? true: false;
- for (int i = 1; i < m; ++i) {
- allOnes[i][0] = allOnes[i-1][0] && (matrix[i][0] == 1);
- }
- for (int j = 1; j < n; ++j) {
- allOnes[0][j] = allOnes[0][j-1] && (matrix[0][j] == 1);
- }
- for (int i = 1; i < m; ++i) {
- for (int j = 1; j < n; ++j) {
- allOnes[i][j] = allOnes[i][j-1] && allOnes[i-1][j] && (matrix[i][j] == 1);
- }
- }
- // ceiling[i][j] -- the row index of the ceiling 0 above matrix[i][j]
- int [][] ceiling = new int [m][n];
- for (int j = 0; j < n; ++j) {
- ceiling[0][j] = (matrix[0][j] == 0) ? 0 : -1;
- }
- for (int i = 1; i < m; ++i) {
- for (int j = 0; j < n; ++j) {
- ceiling[i][j] = (matrix[i][j] == 0) ? i : ceiling[i-1][j];
- }
- }
- // tail[i][j] -- the col index if the tail (righmost) 0 on the left of matrix[i][j]
- int [][] tail = new int [m][n];
- for (int i = 0; i < m; ++i) {
- tail[i][0] = (matrix[i][0] == 0) ? 0 : -1;
- }
- for (int i = 0; i < m; ++i) {
- for (int j = 1; j < n; ++j) {
- tail[i][j] = (matrix[i][j] == 0) ? j : tail[i][j-1];
- }
- }
- // the max edge length of all-one sequre that can be moved from (0, 0) to
- // (i, j)
- int [][] dp = new int [m][n];
- dp[0][0] = (matrix[0][0] == 1) ? 1 : 0;
- for (int i = 1; i < m; ++i) {
- dp[i][0] = (matrix[i][0] == 1) ? dp[i-1][0] : 0;
- }
- for (int j = 1; j < n; ++j) {
- dp[0][j] = (matrix[0][j] == 1) ? dp[0][j-1] : 0;
- }
- for (int i = 1; i < m; ++i) {
- for (int j = 1; j < n; ++j) {
- if (matrix[i][j] == 0) {
- dp[i][j] = 0;
- } else if (allOnes[i][j]) {
- dp[i][j] = Math.min(i + 1, j + 1);
- } else {
- dp[i][j] = Math.max(
- Math.min(dp[i][j-1], i - ceiling[i][j]), // move from left to right
- Math.min(dp[i-1][j], j - tail[i][j])
- );
- }
- }
- }
- return dp[m-1][n-1];
- }
- public static void main(String [] args) {
- int [][] matrix = new int [][] {
- {1,1,1,0},
- {1,1,1,1},
- {1,1,1,1},
- {0,1,1,1},
- {0,1,1,1}
- };
- System.out.println(MaxMoveableRect(matrix));
- }
- }
复制代码
|
|