首页 > 其他 > 详细

LeetCode | Maximal Rectangle

时间:2014-03-08 10:31:00      阅读:480      评论:0      收藏:0      [点我收藏+]

题目

Given a 2D binary matrix filled with 0‘s and 1‘s, find the largest rectangle containing all ones and return its area.

分析

这题最直接的就是O(m^2 * n)的遍历(解法1),从左到右(或者从右到左)得到每个节点左(右)方连续的‘1’(包括自己)的个数。同时,从下到上(或从上到下)计算节点下方(上方)所能构成的矩形的最大值。

这题与Largest Rectangle in Histogram联系紧密,从上到下(或从下到上)得到每个节点上(下)方连续‘1‘(包括自己)的个数。则要得到最大矩形,就是在每一行里进行一次Largest Rectangle in Histogram,这样得到了解法2。虽然这样复杂度降到了O(m * n),但是从LeetCode测试结果上看,解法1还更快些,可能是解法1运气好的时候剪枝比较多。

还有一种非常高大上的解法(解法3),参考http://hi.baidu.com/mzry1992/item/030f9740e0475ef7dc0f6cba,这个是O(m * n)时间复杂度,O(n)空间复杂度。先前两种空间复杂度都是O(m * n)。

解法1

public class MaximalRectangle {
	public int maximalRectangle(char[][] matrix) {
		if (matrix == null || matrix.length == 0) {
			return 0;
		}
		int M = matrix.length;
		int N = matrix[0].length;
		int max = 0;

		// init
		int[][] dp = new int[M + 1][N + 1];

		// dp
		for (int i = M - 1; i >= 0; --i) {
			for (int j = N - 1; j >= 0; --j) {
				if (matrix[i][j] == ‘1‘) {
					dp[i][j] = dp[i][j + 1] + 1;
					int min = dp[i][j];
					int count = 1;
					int tempMax = dp[i][j];
					while (dp[i + count][j] != 0) {
						++count;
						min = Math.min(dp[i + count][j], min);
						tempMax = Math.max(min * count, tempMax);
					}
					max = Math.max(max, tempMax);
				}
			}
		}
		return max;
	}
}
解法2

public class MaximalRectangle {
	public int maximalRectangle(char[][] matrix) {
		if (matrix == null || matrix.length == 0) {
			return 0;
		}

		int M = matrix.length;
		int N = matrix[0].length;

		int max = 0;
		int[][] height = new int[M + 1][N];
		for (int i = 1; i <= M; ++i) {
			Stack<Integer> stack = new Stack<Integer>();
			for (int j = 0; j < N; ++j) {
				if (matrix[i - 1][j] == ‘1‘) {
					height[i][j] = height[i - 1][j] + 1;
				}
				if (stack.isEmpty() || height[i][stack.peek()] <= height[i][j]) {
					stack.push(j);
				} else {
					int index = stack.pop();
					int area = height[i][index]
							* (stack.isEmpty() ? j : (j - stack.peek() - 1));
					max = Math.max(max, area);
					--j;
				}
			}
			while (!stack.isEmpty()) {
				int index = stack.pop();
				int area = height[i][index]
						* (stack.isEmpty() ? N : (N - stack.peek() - 1));
				max = Math.max(max, area);
			}
		}

		return max;
	}
}
解法3

public class MaximalRectangle {
	public int maximalRectangle(char[][] matrix) {
		if (matrix == null || matrix.length == 0) {
			return 0;
		}

		int M = matrix.length;
		int N = matrix[0].length;
		int[] H = new int[N];
		int[] L = new int[N];
		int[] R = new int[N];
		for (int i = 0; i < N; ++i) {
			R[i] = N;
		}

		int ret = 0;
		for (int i = 0; i < M; ++i) {
			int left = 0, right = N;
			// calculate L(i, j) from left to right
			for (int j = 0; j < N; ++j) {
				if (matrix[i][j] == ‘1‘) {
					++H[j];
					L[j] = Math.max(L[j], left);
				} else {
					left = j + 1;
					H[j] = 0;
					L[j] = 0;
					R[j] = N;
				}
			}

			// calculate R(i, j) from right to left
			for (int j = N - 1; j >= 0; --j) {
				if (matrix[i][j] == ‘1‘) {
					R[j] = Math.min(R[j], right);
					ret = Math.max(ret, H[j] * (R[j] - L[j]));
				} else {
					right = j;
				}
			}
		}

		return ret;
	}
}

LeetCode | Maximal Rectangle,布布扣,bubuko.com

LeetCode | Maximal Rectangle

原文:http://blog.csdn.net/perfect8886/article/details/20736635

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!