@@ -94,11 +94,15 @@ tags:
94
94
95
95
<!-- solution:start -->
96
96
97
- ### 方法一:差分有序哈希表
97
+ ### 方法一:差分思想 + 哈希表
98
98
99
- 我们利用差分思想,使用有序哈希表 ` height ` 记录每个位置的高度变化, ` cnt ` 记录建筑物的数量变化。对有序哈希表求前缀和,即可得到每个位置的高度和建筑物数量 。
99
+ 我们可以利用差分思想,用一个哈希表 $\textit{ cnt}$ 记录每个位置的建筑物数量变化,用另一个哈希表 $\textit{d}$ 记录每个位置的高度变化 。
100
100
101
- 最后遍历有序哈希表,对于每个位置,如果高度和建筑物数量都不为 0,则说明该位置有建筑物,判断此时的建筑物是否与上个建筑物的平均高度相同,如果相同,则合并,否则加入结果集。
101
+ 接下来,我们对哈希表 $\textit{d}$ 按照键值进行排序,用一个变量 $\textit{s}$ 记录当前位置的高度和,用一个变量 $\textit{m}$ 记录当前位置的建筑物数量。
102
+
103
+ 然后遍历哈希表 $\textit{d}$,对于每个位置,如果 $\textit{m}$ 不为 0,说明此前有建筑物,我们计算出平均高度,如果当前位置的建筑物与上个建筑物的平均高度相同,则合并,否则加入结果集。
104
+
105
+ 最后返回结果集即可。
102
106
103
107
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为建筑物数量。
104
108
@@ -109,25 +113,26 @@ tags:
109
113
``` python
110
114
class Solution :
111
115
def averageHeightOfBuildings (self , buildings : List[List[int ]]) -> List[List[int ]]:
112
- height = defaultdict(int )
113
116
cnt = defaultdict(int )
114
- for s, e, h in buildings:
115
- cnt[s] += 1
116
- cnt[e] -= 1
117
- height[s] += h
118
- height[e] -= h
117
+ d = defaultdict(int )
118
+ for start, end, height in buildings:
119
+ cnt[start] += 1
120
+ cnt[end] -= 1
121
+ d[start] += height
122
+ d[end] -= height
123
+ s = m = 0
124
+ last = - 1
119
125
ans = []
120
- i = h = n = 0
121
- for j in sorted (cnt.keys()):
122
- if n:
123
- t = [i, j, h // n]
124
- if ans and ans[- 1 ][1 ] == i and ans[- 1 ][2 ] == t[- 1 ]:
125
- ans[- 1 ][1 ] = j
126
+ for k, v in sorted (d.items()):
127
+ if m:
128
+ avg = s // m
129
+ if ans and ans[- 1 ][2 ] == avg and ans[- 1 ][1 ] == last:
130
+ ans[- 1 ][1 ] = k
126
131
else :
127
- ans.append(t )
128
- i = j
129
- h += height[j ]
130
- n += cnt[j]
132
+ ans.append([last, k, avg] )
133
+ s += v
134
+ m += cnt[k ]
135
+ last = k
131
136
return ans
132
137
```
133
138
@@ -136,36 +141,34 @@ class Solution:
136
141
``` java
137
142
class Solution {
138
143
public int [][] averageHeightOfBuildings (int [][] buildings ) {
139
- TreeMap <Integer , Integer > height = new TreeMap <> ();
140
- TreeMap<Integer , Integer > cnt = new TreeMap<> ();
141
- for (var v : buildings) {
142
- int s = v [0 ], e = v [1 ], h = v [2 ];
143
- cnt. put(s, cnt . getOrDefault(s, 0 ) + 1 );
144
- cnt. put(e, cnt . getOrDefault(e, 0 ) - 1 );
145
- height . put(s , height. getOrDefault(s, 0 ) + h );
146
- height . put(e, height. getOrDefault(e, 0 ) - h );
144
+ Map <Integer , Integer > cnt = new HashMap <> ();
145
+ TreeMap<Integer , Integer > d = new TreeMap<> ();
146
+ for (var e : buildings) {
147
+ int start = e [0 ], end = e [1 ], height = e [2 ];
148
+ cnt. merge(start, 1 , Integer :: sum );
149
+ cnt. merge(end, - 1 , Integer :: sum );
150
+ d . merge(start , height, Integer :: sum );
151
+ d . merge(end, - height, Integer :: sum );
147
152
}
148
- int i = 0 , h = 0 , n = 0 ;
149
- List<int[]> res = new ArrayList<> ();
150
- for (int j : cnt. keySet()) {
151
- if (n > 0 ) {
152
- int [] t = new int [] {i, j, h / n};
153
- int k = res. size() - 1 ;
154
- if (k >= 0 && res. get(k)[1 ] == i && res. get(k)[2 ] == t[2 ]) {
155
- res. get(k)[1 ] = j;
153
+ int s = 0 , m = 0 ;
154
+ int last = - 1 ;
155
+ List<int[]> ans = new ArrayList<> ();
156
+ for (var e : d. entrySet()) {
157
+ int k = e. getKey(), v = e. getValue();
158
+ if (m > 0 ) {
159
+ int avg = s / m;
160
+ if (! ans. isEmpty() && ans. get(ans. size() - 1 )[2 ] == avg
161
+ && ans. get(ans. size() - 1 )[1 ] == last) {
162
+ ans. get(ans. size() - 1 )[1 ] = k;
156
163
} else {
157
- res . add(t );
164
+ ans . add(new int [] {last, k, avg} );
158
165
}
159
166
}
160
- h += height. get(j);
161
- n += cnt. get(j);
162
- i = j;
163
- }
164
- int [][] ans = new int [res. size()][3 ];
165
- for (i = 0 ; i < ans. length; ++ i) {
166
- ans[i] = res. get(i);
167
+ s += v;
168
+ m += cnt. get(k);
169
+ last = k;
167
170
}
168
- return ans;
171
+ return ans. toArray( new int [ 0 ][]) ;
169
172
}
170
173
}
171
174
```
@@ -176,27 +179,35 @@ class Solution {
176
179
class Solution {
177
180
public:
178
181
vector<vector<int >> averageHeightOfBuildings(vector<vector<int >>& buildings) {
179
- map<int, int> height, cnt;
180
- for (auto& v : buildings) {
181
- int s = v[ 0] , e = v[ 1] , h = v[ 2] ;
182
- cnt[ s] ++, cnt[ e] --;
183
- height[ s] += h, height[ e] -= h;
182
+ unordered_map<int, int> cnt;
183
+ map<int, int> d;
184
+
185
+ for (const auto& e : buildings) {
186
+ int start = e[0], end = e[1], height = e[2];
187
+ cnt[start]++;
188
+ cnt[end]--;
189
+ d[start] += height;
190
+ d[end] -= height;
184
191
}
192
+
193
+ int s = 0 , m = 0 ;
194
+ int last = -1 ;
185
195
vector<vector<int >> ans;
186
- int i = 0, h = 0, n = 0;
187
- for (auto& [ j, _ ] : cnt ) {
188
- if (n ) {
189
- vector< int > t = {i, j, h / n} ;
190
- if (ans.size () && ans.back()[ 1 ] == i && ans.back()[ 2 ] == t [ 2 ] ) {
191
- ans.back()[ 1] = j ;
196
+
197
+ for (const auto & [k, v ] : d ) {
198
+ if (m > 0 ) {
199
+ int avg = s / m ;
200
+ if (! ans.empty () && ans.back()[2 ] == avg && ans.back()[1 ] == last ) {
201
+ ans.back()[1] = k ;
192
202
} else {
193
- ans.push_back(t );
203
+ ans.push_back({last, k, avg} );
194
204
}
195
205
}
196
- i = j ;
197
- h += height [ j ] ;
198
- n += cnt [ j ] ;
206
+ s += v ;
207
+ m += cnt[k ];
208
+ last = k ;
199
209
}
210
+
200
211
return ans;
201
212
}
202
213
};
@@ -206,39 +217,80 @@ public:
206
217
207
218
``` go
208
219
func averageHeightOfBuildings (buildings [][]int ) [][]int {
209
- height := make(map[int]int)
210
220
cnt := make (map [int ]int )
211
- for _, v := range buildings {
212
- s, e, h := v[0], v[1], v[2]
213
- cnt[s]++
214
- cnt[e]--
215
- height[s] += h
216
- height[e] -= h
221
+ d := make (map [int ]int )
222
+
223
+ for _ , e := range buildings {
224
+ start , end , height := e[0 ], e[1 ], e[2 ]
225
+ cnt[start]++
226
+ cnt[end]--
227
+ d[start] += height
228
+ d[end] -= height
217
229
}
218
- keys := make([]int, len(cnt))
219
- for k := range cnt {
230
+
231
+ s , m := 0 , 0
232
+ last := -1
233
+ var ans [][]int
234
+
235
+ keys := make ([]int , 0 , len (d))
236
+ for k := range d {
220
237
keys = append (keys, k)
221
238
}
222
239
sort.Ints (keys)
223
- i, h, n := 0, 0, 0
224
- ans := [][]int{}
225
- for _, j := range keys {
226
- if n > 0 {
227
- t := []int{i, j, h / n}
228
- if len(ans) > 0 && ans[len(ans)-1][1 ] == i && ans[len(ans)-1][2 ] == t[2] {
229
- ans[len(ans)-1][1] = j
240
+
241
+ for _ , k := range keys {
242
+ v := d[k]
243
+ if m > 0 {
244
+ avg := s / m
245
+ if len (ans) > 0 && ans[len (ans)-1 ][2 ] == avg && ans[len (ans)-1 ][1 ] == last {
246
+ ans[len (ans)-1 ][1 ] = k
230
247
} else {
231
- ans = append(ans, t )
248
+ ans = append (ans, [] int {last, k, avg} )
232
249
}
233
250
}
234
- i = j
235
- h += height[j ]
236
- n += cnt[j]
251
+ s += v
252
+ m += cnt[k ]
253
+ last = k
237
254
}
255
+
238
256
return ans
239
257
}
240
258
```
241
259
260
+ #### TypeScript
261
+
262
+ ``` ts
263
+ function averageHeightOfBuildings(buildings : number [][]): number [][] {
264
+ const cnt = new Map <number , number >();
265
+ const d = new Map <number , number >();
266
+ for (const [start, end, height] of buildings ) {
267
+ cnt .set (start , (cnt .get (start ) || 0 ) + 1 );
268
+ cnt .set (end , (cnt .get (end ) || 0 ) - 1 );
269
+ d .set (start , (d .get (start ) || 0 ) + height );
270
+ d .set (end , (d .get (end ) || 0 ) - height );
271
+ }
272
+ let [s, m] = [0 , 0 ];
273
+ let last = - 1 ;
274
+ const ans: number [][] = [];
275
+ const sortedKeys = Array .from (d .keys ()).sort ((a , b ) => a - b );
276
+ for (const k of sortedKeys ) {
277
+ const v = d .get (k )! ;
278
+ if (m > 0 ) {
279
+ const avg = Math .floor (s / m );
280
+ if (ans .length > 0 && ans .at (- 1 )! [2 ] === avg && ans .at (- 1 )! [1 ] === last ) {
281
+ ans [ans .length - 1 ][1 ] = k ;
282
+ } else {
283
+ ans .push ([last , k , avg ]);
284
+ }
285
+ }
286
+ s += v ;
287
+ m += cnt .get (k )! ;
288
+ last = k ;
289
+ }
290
+ return ans ;
291
+ }
292
+ ```
293
+
242
294
<!-- tabs:end -->
243
295
244
296
<!-- solution:end -->
0 commit comments