[关闭]
@w1024020103 2017-06-30T11:19:45.000000Z 字数 2210 阅读 507

Smallest Rectangle Enclosing Black Pixels

LintCode LeetCode


My first hard problem in LintCode:

这道题是一个用0代表white, 1代表black的棋盘,black是联通的,也就是说整个棋盘只有一个black 区域。给出一份black pixel的坐标(x,y),要返回能够覆盖掉所有black pixels的最小矩形的面积。

这道题我们要依次求出左右上下边界,再计算矩形面积。比如求左边界findLeft(),首先要从y列开始判断是否是全为white的WhiteCol,依次向左,直到找到最靠近y列的那一列全白的列,就是我们要找的左边届。

按照同样的方法找完上下左右边界后,计算面积不能凭直觉地采用 (下边界 - 上边界) * (右边界 - 左边界), 通过画图可以轻易得出面积应该是( 上边界 - 下边界 + 1) * ( 右边界 - 左边界 + 1)。

  1. public class Solution {
  2. /**
  3. * @param image a binary matrix with '0' and '1'
  4. * @param x, y the location of one of the black pixels
  5. * @return an integer
  6. */
  7. public int minArea(char[][] image, int x, int y) {
  8. // Write your code here
  9. if (image == null || image.length == 0 || image[0].length == 0){
  10. return 0;
  11. }
  12. int leftBound;
  13. int rightBound;
  14. int upperBound;
  15. int lowerBound;
  16. leftBound = findLeft(image,x,y);
  17. rightBound = findRight(image,x,y);
  18. upperBound = findUp(image,x,y);
  19. lowerBound = findLow(image,x,y);
  20. return (rightBound - leftBound + 1) * (lowerBound - upperBound + 1);
  21. }
  22. public int findLeft(char[][] image, int x, int y){
  23. int start = 0;
  24. int end = y;
  25. while (start + 1 < end){
  26. int mid = start + (end - start) / 2;
  27. if (isWhiteCol(mid,image)){
  28. start = mid;
  29. } else {
  30. end = mid;
  31. }
  32. }
  33. if (isWhiteCol(end,image)){
  34. return end + 1;
  35. } else if (isWhiteCol(start,image)){
  36. return start + 1;
  37. }
  38. return 0;
  39. }
  40. public int findRight(char[][] image, int x, int y){
  41. int start = y;
  42. int end = image[0].length - 1;
  43. while (start + 1 < end){
  44. int mid = start + (end - start) / 2;
  45. if (isWhiteCol(mid,image)){
  46. end = mid;
  47. } else {
  48. start = mid;
  49. }
  50. }
  51. if (isWhiteCol(start,image)){
  52. return start - 1;
  53. } else if (isWhiteCol(end,image)){
  54. return end - 1;
  55. }
  56. return image[0].length - 1;
  57. }
  58. public int findUp(char[][] image, int x, int y){
  59. int start = 0;
  60. int end = x;
  61. while (start + 1 < end){
  62. int mid = start + (end - start) / 2;
  63. if (isWhiteRow(mid,image)){
  64. start = mid;
  65. } else {
  66. end = mid;
  67. }
  68. }
  69. if (isWhiteRow(end,image)){
  70. return end + 1;
  71. } else if (isWhiteRow(start,image)){
  72. return start + 1;
  73. }
  74. return 0;
  75. }
  76. public int findLow(char[][] image, int x, int y){
  77. int start = x;
  78. int end = image.length - 1;
  79. while (start + 1 < end){
  80. int mid = start + (end - start) / 2;
  81. if (isWhiteRow(mid,image)){
  82. end = mid;
  83. } else {
  84. start = mid;
  85. }
  86. }
  87. if (isWhiteRow(start,image)){
  88. return start - 1;
  89. } else if (isWhiteRow(end,image)){
  90. return end - 1;
  91. } else {
  92. return image.length - 1;
  93. }
  94. }
  95. private boolean isWhiteRow(int row, char [][] image){
  96. for (int i = 0; i < image[0].length; i++){
  97. if (image[row][i] == '1'){
  98. return false;
  99. }
  100. }
  101. return true;
  102. }
  103. private boolean isWhiteCol(int col, char [][] image){
  104. for (int i = 0; i < image.length; i++){
  105. if (image[i][col] == '1'){
  106. return false;
  107. }
  108. }
  109. return true;
  110. }
  111. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注