Skip to content

Commit a1cb3c9

Browse files
committed
feat: add solutions to lc problem: No.0391
No.0391.Perfect Rectangle
1 parent 5f091e9 commit a1cb3c9

File tree

6 files changed

+607
-1
lines changed

6 files changed

+607
-1
lines changed

solution/0300-0399/0391.Perfect Rectangle/README.md

+206-1
Original file line numberDiff line numberDiff line change
@@ -78,22 +78,227 @@
7878

7979
<!-- 这里可写通用的实现逻辑 -->
8080

81+
利用哈希表统计小矩形顶点出现的次数,除了最终大矩形的四个顶点只出现 1 次外,其他顶点的出现次数只有可能是 2 或 4。另外,为了满足条件,小矩形的面积和必须等于大矩形(无重叠)
82+
8183
<!-- tabs:start -->
8284

8385
### **Python3**
8486

8587
<!-- 这里可写当前语言的特殊实现逻辑 -->
8688

8789
```python
88-
90+
class Solution:
91+
def isRectangleCover(self, rectangles: List[List[int]]) -> bool:
92+
area = 0
93+
minX, minY = rectangles[0][0], rectangles[0][1]
94+
maxX, maxY = rectangles[0][2], rectangles[0][3]
95+
cnt = defaultdict(int)
96+
97+
for r in rectangles:
98+
area += (r[2] - r[0]) * (r[3] - r[1])
99+
100+
minX = min(minX, r[0])
101+
minY = min(minY, r[1])
102+
maxX = max(maxX, r[2])
103+
maxY = max(maxY, r[3])
104+
105+
cnt[(r[0], r[1])] += 1
106+
cnt[(r[0], r[3])] += 1
107+
cnt[(r[2], r[3])] += 1
108+
cnt[(r[2], r[1])] += 1
109+
110+
if (
111+
area != (maxX - minX) * (maxY - minY)
112+
or cnt[(minX, minY)] != 1
113+
or cnt[(minX, maxY)] != 1
114+
or cnt[(maxX, maxY)] != 1
115+
or cnt[(maxX, minY)] != 1
116+
):
117+
return False
118+
119+
del cnt[(minX, minY)], cnt[(minX, maxY)], cnt[(maxX, maxY)], cnt[(maxX, minY)]
120+
121+
return all(c == 2 or c == 4 for c in cnt.values())
89122
```
90123

91124
### **Java**
92125

93126
<!-- 这里可写当前语言的特殊实现逻辑 -->
94127

95128
```java
129+
class Solution {
130+
public boolean isRectangleCover(int[][] rectangles) {
131+
long area = 0;
132+
int minX = rectangles[0][0], minY = rectangles[0][1];
133+
int maxX = rectangles[0][2], maxY = rectangles[0][3];
134+
Map<Pair, Integer> cnt = new HashMap<>();
135+
136+
for (int[] r : rectangles) {
137+
area += (r[2] - r[0]) * (r[3] - r[1]);
138+
139+
minX = Math.min(minX, r[0]);
140+
minY = Math.min(minY, r[1]);
141+
maxX = Math.max(maxX, r[2]);
142+
maxY = Math.max(maxY, r[3]);
143+
144+
cnt.merge(new Pair(r[0], r[1]), 1, Integer::sum);
145+
cnt.merge(new Pair(r[0], r[3]), 1, Integer::sum);
146+
cnt.merge(new Pair(r[2], r[3]), 1, Integer::sum);
147+
cnt.merge(new Pair(r[2], r[1]), 1, Integer::sum);
148+
}
149+
150+
if (area != (long) (maxX - minX) * (maxY - minY)
151+
|| cnt.getOrDefault(new Pair(minX, minY), 0) != 1
152+
|| cnt.getOrDefault(new Pair(minX, maxY), 0) != 1
153+
|| cnt.getOrDefault(new Pair(maxX, maxY), 0) != 1
154+
|| cnt.getOrDefault(new Pair(maxX, minY), 0) != 1) {
155+
return false;
156+
}
157+
158+
cnt.remove(new Pair(minX, minY));
159+
cnt.remove(new Pair(minX, maxY));
160+
cnt.remove(new Pair(maxX, maxY));
161+
cnt.remove(new Pair(maxX, minY));
162+
163+
return cnt.values().stream().allMatch(c -> c == 2 || c == 4);
164+
}
165+
166+
private static class Pair {
167+
final int first;
168+
final int second;
169+
170+
Pair(int first, int second) {
171+
this.first = first;
172+
this.second = second;
173+
}
174+
175+
@Override
176+
public boolean equals(Object o) {
177+
if (this == o) {
178+
return true;
179+
}
180+
if (o == null || getClass() != o.getClass()) {
181+
return false;
182+
}
183+
Pair pair = (Pair) o;
184+
return first == pair.first && second == pair.second;
185+
}
186+
187+
@Override
188+
public int hashCode() {
189+
return Objects.hash(first, second);
190+
}
191+
}
192+
}
193+
```
194+
195+
### **C++**
196+
197+
```cpp
198+
class Solution {
199+
public:
200+
bool isRectangleCover(vector<vector<int>>& rectangles) {
201+
long long area = 0;
202+
int minX = rectangles[0][0], minY = rectangles[0][1];
203+
int maxX = rectangles[0][2], maxY = rectangles[0][3];
204+
205+
using pii = pair<int, int>;
206+
map<pii, int> cnt;
207+
208+
for (auto& r : rectangles) {
209+
area += (r[2] - r[0]) * (r[3] - r[1]);
210+
211+
minX = min(minX, r[0]);
212+
minY = min(minY, r[1]);
213+
maxX = max(maxX, r[2]);
214+
maxY = max(maxY, r[3]);
215+
216+
++cnt[{r[0], r[1]}];
217+
++cnt[{r[0], r[3]}];
218+
++cnt[{r[2], r[3]}];
219+
++cnt[{r[2], r[1]}];
220+
}
221+
222+
if (area != (long long)(maxX - minX) * (maxY - minY) ||
223+
cnt[{minX, minY}] != 1 || cnt[{minX, maxY}] != 1 ||
224+
cnt[{maxX, maxY}] != 1 || cnt[{maxX, minY}] != 1) {
225+
return false;
226+
}
227+
228+
cnt.erase({minX, minY});
229+
cnt.erase({minX, maxY});
230+
cnt.erase({maxX, maxY});
231+
cnt.erase({maxX, minY});
232+
233+
return all_of(cnt.begin(), cnt.end(), [](pair<pii, int> e) {
234+
return e.second == 2 || e.second == 4;
235+
});
236+
}
237+
};
238+
```
96239

240+
### **Go**
241+
242+
```go
243+
type pair struct {
244+
first int
245+
second int
246+
}
247+
248+
func isRectangleCover(rectangles [][]int) bool {
249+
area := 0
250+
minX, minY := rectangles[0][0], rectangles[0][1]
251+
maxX, maxY := rectangles[0][2], rectangles[0][3]
252+
253+
cnt := make(map[pair]int)
254+
for _, r := range rectangles {
255+
area += (r[2] - r[0]) * (r[3] - r[1])
256+
257+
minX = min(minX, r[0])
258+
minY = min(minY, r[1])
259+
maxX = max(maxX, r[2])
260+
maxY = max(maxY, r[3])
261+
262+
cnt[pair{r[0], r[1]}]++
263+
cnt[pair{r[0], r[3]}]++
264+
cnt[pair{r[2], r[3]}]++
265+
cnt[pair{r[2], r[1]}]++
266+
}
267+
268+
if area != (maxX-minX)*(maxY-minY) ||
269+
cnt[pair{minX, minY}] != 1 ||
270+
cnt[pair{minX, maxY}] != 1 ||
271+
cnt[pair{maxX, maxY}] != 1 ||
272+
cnt[pair{maxX, minY}] != 1 {
273+
return false
274+
}
275+
276+
delete(cnt, pair{minX, minY})
277+
delete(cnt, pair{minX, maxY})
278+
delete(cnt, pair{maxX, maxY})
279+
delete(cnt, pair{maxX, minY})
280+
281+
for _, c := range cnt {
282+
if c != 2 && c != 4 {
283+
return false
284+
}
285+
}
286+
return true
287+
}
288+
289+
func min(a, b int) int {
290+
if a < b {
291+
return a
292+
}
293+
return b
294+
}
295+
296+
func max(a, b int) int {
297+
if a > b {
298+
return a
299+
}
300+
return b
301+
}
97302
```
98303

99304
### **...**

0 commit comments

Comments
 (0)