@@ -63,7 +63,15 @@ detectSquares.count([11, 10]); // 返回 2 。你可以选择:
63
63
64
64
<!-- 这里可写通用的实现逻辑 -->
65
65
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$ 为数据流中的点的个数。
67
75
68
76
<!-- tabs:start -->
69
77
@@ -74,25 +82,29 @@ detectSquares.count([11, 10]); // 返回 2 。你可以选择:
74
82
``` python
75
83
class DetectSquares :
76
84
def __init__ (self ):
77
- self .mp = defaultdict(Counter)
85
+ self .cnt = defaultdict(Counter)
78
86
79
87
def add (self , point : List[int ]) -> None :
80
88
x, y = point
81
- self .mp [x][y] += 1
89
+ self .cnt [x][y] += 1
82
90
83
91
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
85
95
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]
95
101
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)
96
108
```
97
109
98
110
### ** Java**
@@ -101,35 +113,31 @@ class DetectSquares:
101
113
102
114
``` java
103
115
class DetectSquares {
104
- private Map<Integer , Map<Integer , Integer > > mp = new HashMap<> ();
116
+ private Map<Integer , Map<Integer , Integer > > cnt = new HashMap<> ();
105
117
106
118
public DetectSquares () {
119
+
107
120
}
108
121
109
122
public void add (int [] point ) {
110
123
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);
115
125
}
116
126
117
127
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 ;
122
131
}
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 );
133
141
}
134
142
}
135
143
return ans;
@@ -149,32 +157,34 @@ class DetectSquares {
149
157
``` cpp
150
158
class DetectSquares {
151
159
public:
152
- unordered_map<int, unordered_map<int, int>> mp;
153
-
154
160
DetectSquares() {
161
+
155
162
}
156
163
157
164
void add (vector<int > point) {
158
165
int x = point[ 0] , y = point[ 1] ;
159
- ++mp [ x] [ y ] ;
166
+ ++cnt [ x] [ y ] ;
160
167
}
161
168
162
169
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
+ }
164
174
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];
174
181
}
175
182
}
176
183
return ans;
177
184
}
185
+
186
+ private:
187
+ unordered_map<int, unordered_map<int, int>> cnt;
178
188
};
179
189
180
190
/**
@@ -185,6 +195,47 @@ public:
185
195
* /
186
196
```
187
197
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
+
188
239
### ** ...**
189
240
190
241
```
0 commit comments