zoukankan      html  css  js  c++  java
  • 302. Smallest Rectangle Enclosing Black Pixels

    题目:

    An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. The black pixels are connected, i.e., there is only one black region. Pixels are connected horizontally and vertically. Given the location (x, y) of one of the black pixels, return the area of the smallest (axis-aligned) rectangle that encloses all black pixels.

    For example, given the following image:

    [
      "0010",
      "0110",
      "0100"
    ]
    

    and x = 0y = 2

    Return 6.

    链接:https://leetcode.com/problems/smallest-rectangle-enclosing-black-pixels/#/description

    4/25/2017

    2ms, 47%

    算法班

    用4个二分法查找四个边界。比如查找left时候每次mid其实都要把所有row在mid column的值过一遍。

    非常需要注意细节,x,y都是用来确定row还是column的

    面试有时间可以refactor代码

     1 public class Solution {
     2     public int minArea(char[][] image, int x, int y) {
     3         if (image == null || image.length == 0 || image[0].length == 0) return 0;
     4 
     5         int left, right, top, bottom;
     6 
     7         int start = 0, end = y;
     8         while (start + 1 < end) {
     9             int mid = start + (end - start) / 2;
    10             if (checkThisColumn(image, mid)) {
    11                 end = mid;
    12             } else {
    13                 start = mid;
    14             }
    15         }
    16 
    17         if (checkThisColumn(image, start)) {
    18             left = start;
    19         } else {
    20             left = end;
    21         }
    22 
    23         start = y;
    24         end = image[0].length - 1;
    25         while (start + 1 < end) {
    26             int mid = start + (end - start) / 2;
    27             if (checkThisColumn(image, mid)) {
    28                 start = mid;
    29             } else {
    30                 end = mid;
    31             }
    32         }
    33         if (checkThisColumn(image, end)) {
    34             right = end;
    35         } else {
    36             right = start;
    37         }
    38 
    39         start = 0;
    40         end = x;
    41         while (start + 1 < end) {
    42             int mid = start + (end - start) / 2;
    43             if (checkThisRow(image, mid)) {
    44                 end = mid;
    45             } else {
    46                 start = mid;
    47             }
    48         }
    49         if (checkThisRow(image, start)) {
    50             top = start;
    51         } else {
    52             top = end;
    53         }
    54 
    55         start = x;
    56         end = image.length - 1;
    57         while (start + 1 < end) {
    58             int mid = start + (end - start) / 2;
    59             if (checkThisRow(image, mid)) {
    60                 start = mid;
    61             } else {
    62                 end = mid;
    63             }
    64         }
    65         if (checkThisRow(image, end)) {
    66             bottom = end;
    67         } else {
    68             bottom = start;
    69         }
    70         return (right - left + 1) * (bottom - top + 1);
    71     }
    72 
    73     private boolean checkThisRow(char[][] image, int index) {
    74         if (image == null || image.length == 0 || image[0].length == 0) return false;
    75 
    76         for(int i = 0; i < image[0].length; i++) {
    77             if (image[index][i] == '1') return true;
    78         }
    79         return false;
    80     }
    81 
    82     private boolean checkThisColumn(char[][] image, int index) {
    83         if (image == null || image.length == 0 || image[0].length == 0) return false;
    84         for(int i = 0; i < image.length; i++) {
    85             if (image[i][index] == '1') return true;
    86         }
    87         return false;
    88     }
    89 }

    别人refactor的代码是很好看的

    https://discuss.leetcode.com/topic/29006/c-java-python-binary-search-solution-with-explanation

     1 private char[][] image;
     2 public int minArea(char[][] iImage, int x, int y) {
     3     image = iImage;
     4     int m = image.length, n = image[0].length;
     5     int top = search(0, x, 0, n, true, true);
     6     int bottom = search(x + 1, m, 0, n, false, true);
     7     int left = search(0, y, top, bottom, true, false);
     8     int right = search(y + 1, n, top, bottom, false, false);
     9     return (right - left) * (bottom - top);
    10 }
    11 private boolean isWhite(int mid, int k, boolean isRow) {
    12     return ((isRow) ? image[mid][k] : image[k][mid]) == '0';
    13 }
    14 private int search(int i, int j, int low, int high, boolean opt, boolean isRow) {
    15     while (i != j) {
    16         int k = low, mid = (i + j) / 2;
    17         while (k < high && isWhite(mid, k, isRow)) ++k;
    18         if (k < high == opt)
    19             j = mid;
    20         else
    21             i = mid + 1;
    22     }
    23     return i;
    24 }
    25 //  Runtime: 2 ms

    Python活教材

    https://discuss.leetcode.com/topic/29086/clear-binary-search-python

     1 def minArea(self, image, x, y):
     2     def first(lo, hi, check):
     3         while lo < hi:
     4             mid = (lo + hi) / 2
     5             if check(mid):
     6                 hi = mid
     7             else:
     8                 lo = mid + 1
     9         return lo
    10     top    = first(0, x,             lambda x: '1' in image[x])
    11     bottom = first(x, len(image),    lambda x: '1' not in image[x])
    12     left   = first(0, y,             lambda y: any(row[y] == '1' for row in image))
    13     right  = first(y, len(image[0]), lambda y: all(row[y] == '0' for row in image))
    14     return (bottom - top) * (right - left)

    官方解答:

    https://leetcode.com/articles/smallest-rectangle-enclosing-black-pixels/

    DFS也可以做,但是不如二分法好,DFS的意思是把访问过的1设为0,然后想4个方向去发展检查。

    更多讨论:

    https://discuss.leetcode.com/category/381/smallest-rectangle-enclosing-black-pixels

  • 相关阅读:
    BZOJ 1066 [SCOI2007]蜥蜴 (最大流)
    Codeforces 1092 D2 Great Vova Wall (Version 2) (栈)
    BZOJ 1046 [HAOI2007]上升序列(LIS + 贪心)
    牛客练习赛34 D little w and Exchange(归纳)
    BZOJ 1042 [HAOI2008]硬币购物(完全背包+容斥)
    GTMD并查集!
    2018icpc南京现场赛-G Pyramid(打标找规律+逆元)
    drwxr-xr-x 2 root root 4096 06-29 14:30 Test 分段解释
    Linux里面非常重要的目录
    点击 触发 事件 的 jQuery 写法样式
  • 原文地址:https://www.cnblogs.com/panini/p/6767508.html
Copyright © 2011-2022 走看看