For example, given the following image:
[
"0010",
"0110",
"0100"
]
and x = 0, y = 2,
Return 6.
[备注]
使用二分查找找出上下左右边界,其中上边界和左边界分别是包含了black区域最上面和最左边的pixel,而下边界和右边界分别是black区域下面和右边第一个white pixel,这样处理代码可以精简些,但我的思维方式却是僵硬地去找准确的四个边界。
另外,二分查找中左右边界调整的代码不容易理解,注释中给出了精简前的写法。
[ref]
https://leetcode.com/discuss/71898/1ms-java-binary-search-dfs-is-4ms
public class Solution { // Solution 1: DFS, 4ms public int minArea1(char[][] image, int x, int y) { m = image.length; n = image[0].length; int[] edgePoints = {y, y, x, x}; recur(image, x, y, edgePoints); int width = edgePoints[1] - edgePoints[0] + 1; int height = edgePoints[3] - edgePoints[2] + 1; return width * height; } private int m, n; private int[] xDelta = {0, 0, 1, -1}; private int[] yDelta = {1, -1, 0, 0}; public void recur(char[][] image, int x, int y, int[] edgePoints) { if (image[x][y] != '1') return; // 0 or 2(visited) edgePoints[0] = Math.min(edgePoints[0], y); edgePoints[1] = Math.max(edgePoints[1], y); edgePoints[2] = Math.min(edgePoints[2], x); edgePoints[3] = Math.max(edgePoints[3], x); image[x][y] = '2'; for (int i = 0; i < 4; i++) { int x2 = x + xDelta[i]; int y2 = y + yDelta[i]; if (x2 >= 0 && x2 < m && y2 >= 0 && y2 < n) recur(image, x2, y2, edgePoints); } } // Solution 2: binary search, 1ms public int minArea(char[][] image, int x, int y) { int m = image.length, n = image[0].length; int left = binarySearch(image, 0, y, 0, m, false, true); // search the first pos which belong to black int right = binarySearch(image, y + 1, n, 0, m, false, false); // search the first pos which not belong to black int top = binarySearch(image, 0, x, 0, n, true, true); int bottom = binarySearch(image, x + 1, m, 0, n, true, false); return (right - left) * (bottom - top); } public int binarySearch(char[][] image, int lower, int upper, int min, int max, boolean horizontal, boolean goLower) { int mid; while (lower < upper) { mid = lower + (upper - lower) / 2; boolean inside = false; for (int i = min; i < max; i++) { if ((horizontal ? image[mid][i] : image[i][mid]) == '1') { inside = true; break; } } if (inside == goLower) { upper = mid; } else { lower = mid + 1; } /* if (inside) { // find black pixel, mid is in black region. if (goLower) { upper = mid; } else { lower = mid + 1; } } else { if (goLower) { lower = mid + 1; } else { upper = mid; } } */ } return lower; } }