Skip to content

Commit 2e0c75c

Browse files
committed
feat: add solutions to lc problem: No.0939
No.0939.Minimum Area Rectangle
1 parent 9775bb4 commit 2e0c75c

File tree

7 files changed

+368
-3
lines changed

7 files changed

+368
-3
lines changed

solution/0900-0999/0939.Minimum Area Rectangle/README.md

Lines changed: 132 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,153 @@
3939

4040
<!-- 这里可写通用的实现逻辑 -->
4141

42+
**方法一:哈希表 + 排序 + 枚举**
43+
44+
对于每个点,我们将其横坐标作为键,纵坐标作为值存入哈希表 $d$ 中。对于哈希表中的每个键,我们将其对应的纵坐标按照从小到大的顺序排序。
45+
46+
然后我们从小到大枚举横坐标,对于每个横坐标,我们枚举其对应的纵坐标中的所有点对 $(y_1, y_2)$,其中 $y_1 \lt y_2$。如果我们之前已经遇到过点对 $(y_1, y_2)$,那么就可以用当前的横坐标和之前的横坐标计算出一个矩形的面积。我们用哈希表 $pos$ 记录每个点对 $(y_1, y_2)$ 第一次出现的横坐标,这样我们就可以在常数时间内找到这个横坐标。
47+
48+
最后,我们返回所有矩形的面积中的最小值。
49+
50+
时间复杂度 $O(n^2 \times \log n)$,空间复杂度 $O(n^2)$。其中 $n$ 是点的数量。
51+
4252
<!-- tabs:start -->
4353

4454
### **Python3**
4555

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

4858
```python
49-
59+
class Solution:
60+
def minAreaRect(self, points: List[List[int]]) -> int:
61+
d = defaultdict(list)
62+
for x, y in points:
63+
d[x].append(y)
64+
pos = {}
65+
ans = inf
66+
for x in sorted(d):
67+
ys = d[x]
68+
ys.sort()
69+
n = len(ys)
70+
for i, y1 in enumerate(ys):
71+
for y2 in ys[i + 1 :]:
72+
if (y1, y2) in pos:
73+
ans = min(ans, (x - pos[(y1, y2)]) * (y2 - y1))
74+
pos[(y1, y2)] = x
75+
return 0 if ans == inf else ans
5076
```
5177

5278
### **Java**
5379

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

5682
```java
83+
class Solution {
84+
public int minAreaRect(int[][] points) {
85+
TreeMap<Integer, List<Integer>> d = new TreeMap<>();
86+
for (var p : points) {
87+
int x = p[0], y = p[1];
88+
d.computeIfAbsent(x, k -> new ArrayList<>()).add(y);
89+
}
90+
Map<Integer, Integer> pos = new HashMap<>();
91+
int ans = 1 << 30;
92+
for (var e : d.entrySet()) {
93+
int x = e.getKey();
94+
var ys = e.getValue();
95+
Collections.sort(ys);
96+
int n = ys.size();
97+
for (int i = 0; i < n; ++i) {
98+
int y1 = ys.get(i);
99+
for (int j = i + 1; j < n; ++j) {
100+
int y2 = ys.get(j);
101+
int p = y1 * 40001 + y2;
102+
if (pos.containsKey(p)) {
103+
ans = Math.min(ans, (x - pos.get(p)) * (y2 - y1));
104+
}
105+
pos.put(p, x);
106+
}
107+
}
108+
}
109+
return ans == 1 << 30 ? 0 : ans;
110+
}
111+
}
112+
```
113+
114+
### **C++**
115+
116+
```cpp
117+
class Solution {
118+
public:
119+
int minAreaRect(vector<vector<int>>& points) {
120+
map<int, vector<int>> d;
121+
for (auto& p : points) {
122+
int x = p[0], y = p[1];
123+
d[x].emplace_back(y);
124+
}
125+
unordered_map<int, int> pos;
126+
int ans = 1 << 30;
127+
for (auto& [x, ys] : d) {
128+
sort(ys.begin(), ys.end());
129+
int n = ys.size();
130+
for (int i = 0; i < n; ++i) {
131+
int y1 = ys[i];
132+
for (int j = i + 1; j < n; ++j) {
133+
int y2 = ys[j];
134+
int p = y1 * 40001 + y2;
135+
if (pos.count(p)) {
136+
ans = min(ans, (x - pos[p]) * (y2 - y1));
137+
}
138+
pos[p] = x;
139+
}
140+
}
141+
}
142+
return ans == 1 << 30 ? 0 : ans;
143+
}
144+
};
145+
```
57146
147+
### **Go**
148+
149+
```go
150+
func minAreaRect(points [][]int) int {
151+
d := map[int][]int{}
152+
xs := []int{}
153+
for _, p := range points {
154+
x, y := p[0], p[1]
155+
d[x] = append(d[x], y)
156+
}
157+
for x := range d {
158+
xs = append(xs, x)
159+
}
160+
sort.Ints(xs)
161+
type pair struct{ x, y int }
162+
pos := map[pair]int{}
163+
ans := 1 << 30
164+
for _, x := range xs {
165+
ys := d[x]
166+
sort.Ints(ys)
167+
for i, y1 := range ys {
168+
for _, y2 := range ys[i+1:] {
169+
p := pair{y1, y2}
170+
if x1, ok := pos[p]; ok {
171+
ans = min(ans, (x-x1)*(y2-y1))
172+
}
173+
pos[p] = x
174+
}
175+
}
176+
}
177+
if ans == 1<<30 {
178+
return 0
179+
}
180+
return ans
181+
}
182+
183+
func min(a, b int) int {
184+
if a < b {
185+
return a
186+
}
187+
return b
188+
}
58189
```
59190

60191
### **...**

solution/0900-0999/0939.Minimum Area Rectangle/README_EN.md

Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,134 @@
4040
### **Python3**
4141

4242
```python
43-
43+
class Solution:
44+
def minAreaRect(self, points: List[List[int]]) -> int:
45+
d = defaultdict(list)
46+
for x, y in points:
47+
d[x].append(y)
48+
pos = {}
49+
ans = inf
50+
for x in sorted(d):
51+
ys = d[x]
52+
ys.sort()
53+
n = len(ys)
54+
for i, y1 in enumerate(ys):
55+
for y2 in ys[i + 1 :]:
56+
if (y1, y2) in pos:
57+
ans = min(ans, (x - pos[(y1, y2)]) * (y2 - y1))
58+
pos[(y1, y2)] = x
59+
return 0 if ans == inf else ans
4460
```
4561

4662
### **Java**
4763

4864
```java
65+
class Solution {
66+
public int minAreaRect(int[][] points) {
67+
TreeMap<Integer, List<Integer>> d = new TreeMap<>();
68+
for (var p : points) {
69+
int x = p[0], y = p[1];
70+
d.computeIfAbsent(x, k -> new ArrayList<>()).add(y);
71+
}
72+
Map<Integer, Integer> pos = new HashMap<>();
73+
int ans = 1 << 30;
74+
for (var e : d.entrySet()) {
75+
int x = e.getKey();
76+
var ys = e.getValue();
77+
Collections.sort(ys);
78+
int n = ys.size();
79+
for (int i = 0; i < n; ++i) {
80+
int y1 = ys.get(i);
81+
for (int j = i + 1; j < n; ++j) {
82+
int y2 = ys.get(j);
83+
int p = y1 * 40001 + y2;
84+
if (pos.containsKey(p)) {
85+
ans = Math.min(ans, (x - pos.get(p)) * (y2 - y1));
86+
}
87+
pos.put(p, x);
88+
}
89+
}
90+
}
91+
return ans == 1 << 30 ? 0 : ans;
92+
}
93+
}
94+
```
95+
96+
### **C++**
97+
98+
```cpp
99+
class Solution {
100+
public:
101+
int minAreaRect(vector<vector<int>>& points) {
102+
map<int, vector<int>> d;
103+
for (auto& p : points) {
104+
int x = p[0], y = p[1];
105+
d[x].emplace_back(y);
106+
}
107+
unordered_map<int, int> pos;
108+
int ans = 1 << 30;
109+
for (auto& [x, ys] : d) {
110+
sort(ys.begin(), ys.end());
111+
int n = ys.size();
112+
for (int i = 0; i < n; ++i) {
113+
int y1 = ys[i];
114+
for (int j = i + 1; j < n; ++j) {
115+
int y2 = ys[j];
116+
int p = y1 * 40001 + y2;
117+
if (pos.count(p)) {
118+
ans = min(ans, (x - pos[p]) * (y2 - y1));
119+
}
120+
pos[p] = x;
121+
}
122+
}
123+
}
124+
return ans == 1 << 30 ? 0 : ans;
125+
}
126+
};
127+
```
49128
129+
### **Go**
130+
131+
```go
132+
func minAreaRect(points [][]int) int {
133+
d := map[int][]int{}
134+
xs := []int{}
135+
for _, p := range points {
136+
x, y := p[0], p[1]
137+
d[x] = append(d[x], y)
138+
}
139+
for x := range d {
140+
xs = append(xs, x)
141+
}
142+
sort.Ints(xs)
143+
type pair struct{ x, y int }
144+
pos := map[pair]int{}
145+
ans := 1 << 30
146+
for _, x := range xs {
147+
ys := d[x]
148+
sort.Ints(ys)
149+
for i, y1 := range ys {
150+
for _, y2 := range ys[i+1:] {
151+
p := pair{y1, y2}
152+
if x1, ok := pos[p]; ok {
153+
ans = min(ans, (x-x1)*(y2-y1))
154+
}
155+
pos[p] = x
156+
}
157+
}
158+
}
159+
if ans == 1<<30 {
160+
return 0
161+
}
162+
return ans
163+
}
164+
165+
func min(a, b int) int {
166+
if a < b {
167+
return a
168+
}
169+
return b
170+
}
50171
```
51172

52173
### **...**
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class Solution {
2+
public:
3+
int minAreaRect(vector<vector<int>>& points) {
4+
map<int, vector<int>> d;
5+
for (auto& p : points) {
6+
int x = p[0], y = p[1];
7+
d[x].emplace_back(y);
8+
}
9+
unordered_map<int, int> pos;
10+
int ans = 1 << 30;
11+
for (auto& [x, ys] : d) {
12+
sort(ys.begin(), ys.end());
13+
int n = ys.size();
14+
for (int i = 0; i < n; ++i) {
15+
int y1 = ys[i];
16+
for (int j = i + 1; j < n; ++j) {
17+
int y2 = ys[j];
18+
int p = y1 * 40001 + y2;
19+
if (pos.count(p)) {
20+
ans = min(ans, (x - pos[p]) * (y2 - y1));
21+
}
22+
pos[p] = x;
23+
}
24+
}
25+
}
26+
return ans == 1 << 30 ? 0 : ans;
27+
}
28+
};
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
func minAreaRect(points [][]int) int {
2+
d := map[int][]int{}
3+
xs := []int{}
4+
for _, p := range points {
5+
x, y := p[0], p[1]
6+
d[x] = append(d[x], y)
7+
}
8+
for x := range d {
9+
xs = append(xs, x)
10+
}
11+
sort.Ints(xs)
12+
type pair struct{ x, y int }
13+
pos := map[pair]int{}
14+
ans := 1 << 30
15+
for _, x := range xs {
16+
ys := d[x]
17+
sort.Ints(ys)
18+
for i, y1 := range ys {
19+
for _, y2 := range ys[i+1:] {
20+
p := pair{y1, y2}
21+
if x1, ok := pos[p]; ok {
22+
ans = min(ans, (x-x1)*(y2-y1))
23+
}
24+
pos[p] = x
25+
}
26+
}
27+
}
28+
if ans == 1<<30 {
29+
return 0
30+
}
31+
return ans
32+
}
33+
34+
func min(a, b int) int {
35+
if a < b {
36+
return a
37+
}
38+
return b
39+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
class Solution {
2+
public int minAreaRect(int[][] points) {
3+
TreeMap<Integer, List<Integer>> d = new TreeMap<>();
4+
for (var p : points) {
5+
int x = p[0], y = p[1];
6+
d.computeIfAbsent(x, k -> new ArrayList<>()).add(y);
7+
}
8+
Map<Integer, Integer> pos = new HashMap<>();
9+
int ans = 1 << 30;
10+
for (var e : d.entrySet()) {
11+
int x = e.getKey();
12+
var ys = e.getValue();
13+
Collections.sort(ys);
14+
int n = ys.size();
15+
for (int i = 0; i < n; ++i) {
16+
int y1 = ys.get(i);
17+
for (int j = i + 1; j < n; ++j) {
18+
int y2 = ys.get(j);
19+
int p = y1 * 40001 + y2;
20+
if (pos.containsKey(p)) {
21+
ans = Math.min(ans, (x - pos.get(p)) * (y2 - y1));
22+
}
23+
pos.put(p, x);
24+
}
25+
}
26+
}
27+
return ans == 1 << 30 ? 0 : ans;
28+
}
29+
}

0 commit comments

Comments
 (0)