forked from shuboc/LeetCode-2
-
Notifications
You must be signed in to change notification settings - Fork 1
/
smallest-rectangle-enclosing-black-pixels.cpp
128 lines (111 loc) · 4.87 KB
/
smallest-rectangle-enclosing-black-pixels.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Time: O(nlogn)
// Space: O(1)
// Using template.
class Solution {
public:
int minArea(vector<vector<char>>& image, int x, int y) {
using namespace std::placeholders; // for _1, _2, _3...
const auto searchColumns =
[](const vector<vector<char>>& image, bool has_one, const int mid) {
return has_one == any_of(image.cbegin(), image.cend(),
[=](const vector<char>& row) { return row[mid] == '1'; });
};
const auto searchRows =
[](const vector<vector<char>>& image, bool has_one, const int mid) {
return has_one == any_of(image[mid].cbegin(), image[mid].cend(),
[](const char& col) { return col == '1'; });
};
const int left = binarySearch(0, y - 1, bind(searchColumns, image, true, _1));
const int right = binarySearch(y + 1, image[0].size() - 1, bind(searchColumns, image, false, _1));
const int top = binarySearch(0, x - 1, bind(searchRows, image, true, _1));
const int bottom = binarySearch(x + 1, image.size() - 1, bind(searchRows, image, false, _1));
return (right - left) * (bottom - top);
}
private:
template<typename T>
int binarySearch(int left, int right, const T& find) {
while (left <= right) {
const int mid = left + (right - left) / 2;
if (find(mid)) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return left;
}
};
// Using std::bind().
class Solution2 {
public:
int minArea(vector<vector<char>>& image, int x, int y) {
using namespace std::placeholders; // for _1, _2, _3...
const auto searchColumns =
[](const vector<vector<char>>& image, bool has_one, const int mid) {
return has_one == any_of(image.cbegin(), image.cend(),
[=](const vector<char>& row) { return row[mid] == '1'; });
};
const auto searchRows =
[](const vector<vector<char>>& image, bool has_one, const int mid) {
return has_one == any_of(image[mid].cbegin(), image[mid].cend(),
[](const char& col) { return col == '1'; });
};
function<bool(const int)> findLeft = bind(searchColumns, image, true, _1);
const int left = binarySearch(0, y - 1, findLeft);
function<bool(const int)> findRight = bind(searchColumns, image, false, _1);
const int right = binarySearch(y + 1, image[0].size() - 1, findRight);
function<bool(const int)> findTop = bind(searchRows, image, true, _1);
const int top = binarySearch(0, x - 1, findTop);
function<bool(const int)> findBottom = bind(searchRows, image, false, _1);
const int bottom = binarySearch(x + 1, image.size() - 1, findBottom);
return (right - left) * (bottom - top);
}
private:
int binarySearch(int left, int right, function<bool(const int)>& find) {
while (left <= right) {
const int mid = left + (right - left) / 2;
if (find(mid)) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return left;
}
};
// Using lambda.
class Solution3 {
public:
int minArea(vector<vector<char>>& image, int x, int y) {
const auto searchColumns =
[](const vector<vector<char>>& image, bool has_one, const int mid) {
return has_one == any_of(image.cbegin(), image.cend(),
[=](const vector<char>& row) { return row[mid] == '1'; });
};
const auto searchRows =
[](const vector<vector<char>>& image, bool has_one, const int mid) {
return has_one == any_of(image[mid].cbegin(), image[mid].cend(),
[](const char& col) { return col == '1'; });
};
const int left = binarySearch(0, y - 1, searchColumns, image, true);
const int right = binarySearch(y + 1, image[0].size() - 1, searchColumns, image, false);
const int top = binarySearch(0, x - 1, searchRows, image, true);
const int bottom = binarySearch(x + 1, image.size() - 1, searchRows, image, false);
return (right - left) * (bottom - top);
}
private:
int binarySearch(int left, int right,
const function<bool(const vector<vector<char>>&, bool, const int)>& find,
const vector<vector<char>>& image,
bool has_one) {
while (left <= right) {
const int mid = left + (right - left) / 2;
if (find(image, has_one, mid)) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return left;
}
};