Skip to content

Commit 6646f0e

Browse files
committed
feat: add solutions to lc problem: No.2013
No.2013.Detect Squares
1 parent 5ab2803 commit 6646f0e

File tree

6 files changed

+273
-141
lines changed

6 files changed

+273
-141
lines changed

solution/2000-2099/2013.Detect Squares/README.md

+96-45
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,15 @@ detectSquares.count([11, 10]); // 返回 2 。你可以选择:
6363

6464
<!-- 这里可写通用的实现逻辑 -->
6565

66-
哈希表实现。
66+
**方法一:哈希表**
67+
68+
我们可以用一个哈希表 $cnt$ 维护所有点的信息,其中 $cnt[x][y]$ 表示点 $(x, y)$ 的个数。
69+
70+
当调用 $add(x, y)$ 方法时,我们将 $cnt[x][y]$ 的值加 $1$。
71+
72+
当调用 $count(x_1, y_1)$ 方法时,我们需要获取另外的三个点,构成一个轴对齐正方形。我们可以枚举平行于 $x$ 轴且与 $(x_1, y_1)$ 的距离为 $d$ 的点 $(x_2, y_1)$,如果存在这样的点,根据这两个点,我们可以确定另外两个点为 $(x_1, y_1 + d)$ 和 $(x_2, y_1 + d)$,或者 $(x_1, y_1 - d)$ 和 $(x_2, y_1 - d)$。我们将这两种情况的方案数累加即可。
73+
74+
时间复杂度方面,调用 $add(x, y)$ 方法的时间复杂度为 $O(1)$,调用 $count(x_1, y_1)$ 方法的时间复杂度为 $O(n)$;空间复杂度为 $O(n)$。其中 $n$ 为数据流中的点的个数。
6775

6876
<!-- tabs:start -->
6977

@@ -74,25 +82,29 @@ detectSquares.count([11, 10]); // 返回 2 。你可以选择:
7482
```python
7583
class DetectSquares:
7684
def __init__(self):
77-
self.mp = defaultdict(Counter)
85+
self.cnt = defaultdict(Counter)
7886

7987
def add(self, point: List[int]) -> None:
8088
x, y = point
81-
self.mp[x][y] += 1
89+
self.cnt[x][y] += 1
8290

8391
def count(self, point: List[int]) -> int:
84-
x, y = point
92+
x1, y1 = point
93+
if x1 not in self.cnt:
94+
return 0
8595
ans = 0
86-
if x not in self.mp:
87-
return ans
88-
xcnt = self.mp[x]
89-
90-
for x1, counter in self.mp.items():
91-
if x1 != x:
92-
d = x1 - x
93-
ans += xcnt[y + d] * counter[y] * counter[y + d]
94-
ans += xcnt[y - d] * counter[y] * counter[y - d]
96+
for x2 in self.cnt.keys():
97+
if x2 != x1:
98+
d = x2 - x1
99+
ans += self.cnt[x2][y1] * self.cnt[x1][y1 + d] * self.cnt[x2][y1 + d]
100+
ans += self.cnt[x2][y1] * self.cnt[x1][y1 - d] * self.cnt[x2][y1 - d]
95101
return ans
102+
103+
104+
# Your DetectSquares object will be instantiated and called as such:
105+
# obj = DetectSquares()
106+
# obj.add(point)
107+
# param_2 = obj.count(point)
96108
```
97109

98110
### **Java**
@@ -101,35 +113,31 @@ class DetectSquares:
101113

102114
```java
103115
class DetectSquares {
104-
private Map<Integer, Map<Integer, Integer>> mp = new HashMap<>();
116+
private Map<Integer, Map<Integer, Integer>> cnt = new HashMap<>();
105117

106118
public DetectSquares() {
119+
107120
}
108121

109122
public void add(int[] point) {
110123
int x = point[0], y = point[1];
111-
if (!mp.containsKey(x)) {
112-
mp.put(x, new HashMap<>());
113-
}
114-
mp.get(x).put(y, mp.get(x).getOrDefault(y, 0) + 1);
124+
cnt.computeIfAbsent(x, k -> new HashMap<>()).merge(y, 1, Integer::sum);
115125
}
116126

117127
public int count(int[] point) {
118-
int x = point[0], y = point[1];
119-
int ans = 0;
120-
if (!mp.containsKey(x)) {
121-
return ans;
128+
int x1 = point[0], y1 = point[1];
129+
if (!cnt.containsKey(x1)) {
130+
return 0;
122131
}
123-
Map<Integer, Integer> xcnt = mp.get(x);
124-
for (Map.Entry<Integer, Map<Integer, Integer>> e : mp.entrySet()) {
125-
int x1 = e.getKey();
126-
Map<Integer, Integer> counter = e.getValue();
127-
if (x1 != x) {
128-
int d = x1 - x;
129-
ans += xcnt.getOrDefault(y + d, 0) * counter.getOrDefault(y, 0)
130-
* counter.getOrDefault(y + d, 0);
131-
ans += xcnt.getOrDefault(y - d, 0) * counter.getOrDefault(y, 0)
132-
* counter.getOrDefault(y - d, 0);
132+
int ans = 0;
133+
for (var e : cnt.entrySet()) {
134+
int x2 = e.getKey();
135+
if (x2 != x1) {
136+
int d = x2 - x1;
137+
var cnt1 = cnt.get(x1);
138+
var cnt2 = e.getValue();
139+
ans += cnt2.getOrDefault(y1, 0) * cnt1.getOrDefault(y1 + d, 0) * cnt2.getOrDefault(y1 + d, 0);
140+
ans += cnt2.getOrDefault(y1, 0) * cnt1.getOrDefault(y1 - d, 0) * cnt2.getOrDefault(y1 - d, 0);
133141
}
134142
}
135143
return ans;
@@ -149,32 +157,34 @@ class DetectSquares {
149157
```cpp
150158
class DetectSquares {
151159
public:
152-
unordered_map<int, unordered_map<int, int>> mp;
153-
154160
DetectSquares() {
161+
155162
}
156163

157164
void add(vector<int> point) {
158165
int x = point[0], y = point[1];
159-
++mp[x][y];
166+
++cnt[x][y];
160167
}
161168

162169
int count(vector<int> point) {
163-
int x = point[0], y = point[1];
170+
int x1 = point[0], y1 = point[1];
171+
if (!cnt.count(x1)) {
172+
return 0;
173+
}
164174
int ans = 0;
165-
if (!mp.count(x)) return ans;
166-
auto xcnt = mp[x];
167-
for (auto e : mp) {
168-
int x1 = e.first;
169-
auto counter = e.second;
170-
if (x1 != x) {
171-
int d = x1 - x;
172-
ans += xcnt[y + d] * counter[y] * counter[y + d];
173-
ans += xcnt[y - d] * counter[y] * counter[y - d];
175+
for (auto& [x2, cnt2] : cnt) {
176+
if (x2 != x1) {
177+
int d = x2 - x1;
178+
auto& cnt1 = cnt[x1];
179+
ans += cnt2[y1] * cnt1[y1 + d] * cnt2[y1 + d];
180+
ans += cnt2[y1] * cnt1[y1 - d] * cnt2[y1 - d];
174181
}
175182
}
176183
return ans;
177184
}
185+
186+
private:
187+
unordered_map<int, unordered_map<int, int>> cnt;
178188
};
179189

180190
/**
@@ -185,6 +195,47 @@ public:
185195
*/
186196
```
187197
198+
### **Go**
199+
200+
```go
201+
type DetectSquares struct {
202+
cnt map[int]map[int]int
203+
}
204+
205+
func Constructor() DetectSquares {
206+
return DetectSquares{map[int]map[int]int{}}
207+
}
208+
209+
func (this *DetectSquares) Add(point []int) {
210+
x, y := point[0], point[1]
211+
if _, ok := this.cnt[x]; !ok {
212+
this.cnt[x] = map[int]int{}
213+
}
214+
this.cnt[x][y]++
215+
}
216+
217+
func (this *DetectSquares) Count(point []int) (ans int) {
218+
x1, y1 := point[0], point[1]
219+
if cnt1, ok := this.cnt[x1]; ok {
220+
for x2, cnt2 := range this.cnt {
221+
if x2 != x1 {
222+
d := x2 - x1
223+
ans += cnt2[y1] * cnt1[y1+d] * cnt2[y1+d]
224+
ans += cnt2[y1] * cnt1[y1-d] * cnt2[y1-d]
225+
}
226+
}
227+
}
228+
return
229+
}
230+
231+
/**
232+
* Your DetectSquares object will be instantiated and called as such:
233+
* obj := Constructor();
234+
* obj.Add(point);
235+
* param_2 := obj.Count(point);
236+
*/
237+
```
238+
188239
### **...**
189240

190241
```

solution/2000-2099/2013.Detect Squares/README_EN.md

+91-48
Original file line numberDiff line numberDiff line change
@@ -64,60 +64,60 @@ detectSquares.count([11, 10]); // return 2. You can choose:
6464
```python
6565
class DetectSquares:
6666
def __init__(self):
67-
self.mp = defaultdict(Counter)
67+
self.cnt = defaultdict(Counter)
6868

6969
def add(self, point: List[int]) -> None:
7070
x, y = point
71-
self.mp[x][y] += 1
71+
self.cnt[x][y] += 1
7272

7373
def count(self, point: List[int]) -> int:
74-
x, y = point
74+
x1, y1 = point
75+
if x1 not in self.cnt:
76+
return 0
7577
ans = 0
76-
if x not in self.mp:
77-
return ans
78-
xcnt = self.mp[x]
79-
80-
for x1, counter in self.mp.items():
81-
if x1 != x:
82-
d = x1 - x
83-
ans += xcnt[y + d] * counter[y] * counter[y + d]
84-
ans += xcnt[y - d] * counter[y] * counter[y - d]
78+
for x2 in self.cnt.keys():
79+
if x2 != x1:
80+
d = x2 - x1
81+
ans += self.cnt[x2][y1] * self.cnt[x1][y1 + d] * self.cnt[x2][y1 + d]
82+
ans += self.cnt[x2][y1] * self.cnt[x1][y1 - d] * self.cnt[x2][y1 - d]
8583
return ans
84+
85+
86+
# Your DetectSquares object will be instantiated and called as such:
87+
# obj = DetectSquares()
88+
# obj.add(point)
89+
# param_2 = obj.count(point)
8690
```
8791

8892
### **Java**
8993

9094
```java
9195
class DetectSquares {
92-
private Map<Integer, Map<Integer, Integer>> mp = new HashMap<>();
96+
private Map<Integer, Map<Integer, Integer>> cnt = new HashMap<>();
9397

9498
public DetectSquares() {
95-
}
9699

100+
}
101+
97102
public void add(int[] point) {
98103
int x = point[0], y = point[1];
99-
if (!mp.containsKey(x)) {
100-
mp.put(x, new HashMap<>());
101-
}
102-
mp.get(x).put(y, mp.get(x).getOrDefault(y, 0) + 1);
104+
cnt.computeIfAbsent(x, k -> new HashMap<>()).merge(y, 1, Integer::sum);
103105
}
104-
106+
105107
public int count(int[] point) {
106-
int x = point[0], y = point[1];
107-
int ans = 0;
108-
if (!mp.containsKey(x)) {
109-
return ans;
108+
int x1 = point[0], y1 = point[1];
109+
if (!cnt.containsKey(x1)) {
110+
return 0;
110111
}
111-
Map<Integer, Integer> xcnt = mp.get(x);
112-
for (Map.Entry<Integer, Map<Integer, Integer>> e : mp.entrySet()) {
113-
int x1 = e.getKey();
114-
Map<Integer, Integer> counter = e.getValue();
115-
if (x1 != x) {
116-
int d = x1 - x;
117-
ans += xcnt.getOrDefault(y + d, 0) * counter.getOrDefault(y, 0)
118-
* counter.getOrDefault(y + d, 0);
119-
ans += xcnt.getOrDefault(y - d, 0) * counter.getOrDefault(y, 0)
120-
* counter.getOrDefault(y - d, 0);
112+
int ans = 0;
113+
for (var e : cnt.entrySet()) {
114+
int x2 = e.getKey();
115+
if (x2 != x1) {
116+
int d = x2 - x1;
117+
var cnt1 = cnt.get(x1);
118+
var cnt2 = e.getValue();
119+
ans += cnt2.getOrDefault(y1, 0) * cnt1.getOrDefault(y1 + d, 0) * cnt2.getOrDefault(y1 + d, 0);
120+
ans += cnt2.getOrDefault(y1, 0) * cnt1.getOrDefault(y1 - d, 0) * cnt2.getOrDefault(y1 - d, 0);
121121
}
122122
}
123123
return ans;
@@ -137,32 +137,34 @@ class DetectSquares {
137137
```cpp
138138
class DetectSquares {
139139
public:
140-
unordered_map<int, unordered_map<int, int>> mp;
141-
142140
DetectSquares() {
143-
}
144141

142+
}
143+
145144
void add(vector<int> point) {
146145
int x = point[0], y = point[1];
147-
++mp[x][y];
146+
++cnt[x][y];
148147
}
149-
148+
150149
int count(vector<int> point) {
151-
int x = point[0], y = point[1];
150+
int x1 = point[0], y1 = point[1];
151+
if (!cnt.count(x1)) {
152+
return 0;
153+
}
152154
int ans = 0;
153-
if (!mp.count(x)) return ans;
154-
auto xcnt = mp[x];
155-
for (auto e : mp) {
156-
int x1 = e.first;
157-
auto counter = e.second;
158-
if (x1 != x) {
159-
int d = x1 - x;
160-
ans += xcnt[y + d] * counter[y] * counter[y + d];
161-
ans += xcnt[y - d] * counter[y] * counter[y - d];
155+
for (auto& [x2, cnt2] : cnt) {
156+
if (x2 != x1) {
157+
int d = x2 - x1;
158+
auto& cnt1 = cnt[x1];
159+
ans += cnt2[y1] * cnt1[y1 + d] * cnt2[y1 + d];
160+
ans += cnt2[y1] * cnt1[y1 - d] * cnt2[y1 - d];
162161
}
163162
}
164163
return ans;
165164
}
165+
166+
private:
167+
unordered_map<int, unordered_map<int, int>> cnt;
166168
};
167169

168170
/**
@@ -173,6 +175,47 @@ public:
173175
*/
174176
```
175177
178+
### **Go**
179+
180+
```go
181+
type DetectSquares struct {
182+
cnt map[int]map[int]int
183+
}
184+
185+
func Constructor() DetectSquares {
186+
return DetectSquares{map[int]map[int]int{}}
187+
}
188+
189+
func (this *DetectSquares) Add(point []int) {
190+
x, y := point[0], point[1]
191+
if _, ok := this.cnt[x]; !ok {
192+
this.cnt[x] = map[int]int{}
193+
}
194+
this.cnt[x][y]++
195+
}
196+
197+
func (this *DetectSquares) Count(point []int) (ans int) {
198+
x1, y1 := point[0], point[1]
199+
if cnt1, ok := this.cnt[x1]; ok {
200+
for x2, cnt2 := range this.cnt {
201+
if x2 != x1 {
202+
d := x2 - x1
203+
ans += cnt2[y1] * cnt1[y1+d] * cnt2[y1+d]
204+
ans += cnt2[y1] * cnt1[y1-d] * cnt2[y1-d]
205+
}
206+
}
207+
}
208+
return
209+
}
210+
211+
/**
212+
* Your DetectSquares object will be instantiated and called as such:
213+
* obj := Constructor();
214+
* obj.Add(point);
215+
* param_2 := obj.Count(point);
216+
*/
217+
```
218+
176219
### **...**
177220

178221
```

0 commit comments

Comments
 (0)