@@ -101,32 +101,275 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3661.Ma
101
101
102
102
<!-- solution:start -->
103
103
104
- ### 方法一
104
+ ### 方法一:记忆化搜索
105
105
106
- <!-- tabs:start -->
106
+ 我们首先将每个机器人与其射程一起存储在一个数组中,并按照机器人的位置进行排序。同时,我们对墙壁的位置进行排序。接下来,我们使用深度优先搜索(DFS)来计算每个机器人可以摧毁的墙壁数量,并使用记忆化搜索来避免重复计算。
107
+
108
+ 我们设计一个函数 $\text{dfs}(i, j)$,其中 $i$ 表示当前考虑的机器人索引,而 $j$ 表示下一个机器人的发射方向(0 表示左,1 表示右)的时候,所能摧毁的墙壁数量。答案为 $\text{dfs}(n - 1, 1)$,边界状态下的 $j$ 可以取 0 或 1。
109
+
110
+ 函数 $\text{dfs}(i, j)$ 的执行逻辑如下:
111
+
112
+ 如果 $i \lt 0$,表示所有机器人都已经考虑过,返回 0。
113
+
114
+ 否则,对于当前机器人,有两种发射方向可供选择。
115
+
116
+ 如果选择** 向左** 发射,我们需要计算左侧的射程范围 $[ \text{left}, \text{robot}[ i] [ 0 ]] $,并通过二分查找,计算此范围内可以摧毁的墙壁数量。这种情况下一共可以摧毁 $\text{dfs}(i - 1, 0) + \text{count}$ 墙壁,其中 $\text{count}$ 是当前机器人向左发射时摧毁的墙壁数量。
117
+
118
+ 如果选择** 向右** 发射,我们需要计算右侧的射程范围 $[ \text{robot}[ i] [ 0 ] , \text{right}] $,并通过二分查找,计算此范围内可以摧毁的墙壁数量。这种情况下一共可以摧毁 $\text{dfs}(i - 1, 1) + \text{count}$ 墙壁,其中 $\text{count}$ 是当前机器人向右发射时摧毁的墙壁数量。
119
+
120
+ 函数的返回值为两种发射方向所能摧毁墙壁数量的最大值。
121
+
122
+ 时间复杂度 $O(n \times \log n + m \times \log m)$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别是机器人和墙壁的数量。
107
123
108
124
#### Python3
109
125
110
126
``` python
111
-
127
+ class Solution :
128
+ def maxWalls (self , robots : List[int ], distance : List[int ], walls : List[int ]) -> int :
129
+ n = len (robots)
130
+ arr = sorted (zip (robots, distance), key = lambda x : x[0 ])
131
+ walls.sort()
132
+
133
+ @cache
134
+ def dfs (i : int , j : int ) -> int :
135
+ if i < 0 :
136
+ return 0
137
+ left = arr[i][0 ] - arr[i][1 ]
138
+ if i > 0 :
139
+ left = max (left, arr[i - 1 ][0 ] + 1 )
140
+ l = bisect_left(walls, left)
141
+ r = bisect_left(walls, arr[i][0 ] + 1 )
142
+ ans = dfs(i - 1 , 0 ) + r - l
143
+ right = arr[i][0 ] + arr[i][1 ]
144
+ if i + 1 < n:
145
+ if j == 0 :
146
+ right = min (right, arr[i + 1 ][0 ] - arr[i + 1 ][1 ] - 1 )
147
+ else :
148
+ right = min (right, arr[i + 1 ][0 ] - 1 )
149
+ l = bisect_left(walls, arr[i][0 ])
150
+ r = bisect_left(walls, right + 1 )
151
+ ans = max (ans, dfs(i - 1 , 1 ) + r - l)
152
+ return ans
153
+
154
+ return dfs(n - 1 , 1 )
112
155
```
113
156
114
157
#### Java
115
158
116
159
``` java
117
-
160
+ class Solution {
161
+ private Integer [][] f;
162
+ private int [][] arr;
163
+ private int [] walls;
164
+ private int n;
165
+
166
+ public int maxWalls (int [] robots , int [] distance , int [] walls ) {
167
+ n = robots. length;
168
+ arr = new int [n][2 ];
169
+ for (int i = 0 ; i < n; i++ ) {
170
+ arr[i][0 ] = robots[i];
171
+ arr[i][1 ] = distance[i];
172
+ }
173
+ Arrays . sort(arr, Comparator . comparingInt(a - > a[0 ]));
174
+ Arrays . sort(walls);
175
+ this . walls = walls;
176
+ f = new Integer [n][2 ];
177
+ return dfs(n - 1 , 1 );
178
+ }
179
+
180
+ private int dfs (int i , int j ) {
181
+ if (i < 0 ) {
182
+ return 0 ;
183
+ }
184
+ if (f[i][j] != null ) {
185
+ return f[i][j];
186
+ }
187
+
188
+ int left = arr[i][0 ] - arr[i][1 ];
189
+ if (i > 0 ) {
190
+ left = Math . max(left, arr[i - 1 ][0 ] + 1 );
191
+ }
192
+ int l = lowerBound(walls, left);
193
+ int r = lowerBound(walls, arr[i][0 ] + 1 );
194
+ int ans = dfs(i - 1 , 0 ) + (r - l);
195
+
196
+ int right = arr[i][0 ] + arr[i][1 ];
197
+ if (i + 1 < n) {
198
+ if (j == 0 ) {
199
+ right = Math . min(right, arr[i + 1 ][0 ] - arr[i + 1 ][1 ] - 1 );
200
+ } else {
201
+ right = Math . min(right, arr[i + 1 ][0 ] - 1 );
202
+ }
203
+ }
204
+ l = lowerBound(walls, arr[i][0 ]);
205
+ r = lowerBound(walls, right + 1 );
206
+ ans = Math . max(ans, dfs(i - 1 , 1 ) + (r - l));
207
+ return f[i][j] = ans;
208
+ }
209
+
210
+ private int lowerBound (int [] arr , int target ) {
211
+ int idx = Arrays . binarySearch(arr, target);
212
+ if (idx < 0 ) {
213
+ return - idx - 1 ;
214
+ }
215
+ return idx;
216
+ }
217
+ }
118
218
```
119
219
120
220
#### C++
121
221
122
222
``` cpp
123
-
223
+ class Solution {
224
+ public:
225
+ int maxWalls(vector<int >& robots, vector<int >& distance, vector<int >& walls) {
226
+ int n = robots.size();
227
+ vector<pair<int, int>> arr(n);
228
+ for (int i = 0; i < n; i++) {
229
+ arr[ i] = {robots[ i] , distance[ i] };
230
+ }
231
+ ranges::sort(arr, {}, &pair<int, int>::first);
232
+ ranges::sort(walls);
233
+
234
+ vector f(n, vector<int>(2, -1));
235
+
236
+ auto dfs = [&](this auto&& dfs, int i, int j) -> int {
237
+ if (i < 0) {
238
+ return 0;
239
+ }
240
+ if (f[i][j] != -1 ) {
241
+ return f[i][j];
242
+ }
243
+
244
+ int left = arr[i].first - arr[i].second;
245
+ if (i > 0) {
246
+ left = max(left, arr[i - 1].first + 1);
247
+ }
248
+ int l = ranges::lower_bound(walls, left) - walls.begin();
249
+ int r = ranges::lower_bound(walls, arr[i].first + 1) - walls.begin();
250
+ int ans = dfs(i - 1, 0) + (r - l);
251
+
252
+ int right = arr[i].first + arr[i].second;
253
+ if (i + 1 < n) {
254
+ if (j == 0) {
255
+ right = min(right, arr[i + 1].first - arr[i + 1].second - 1);
256
+ } else {
257
+ right = min(right, arr[i + 1].first - 1);
258
+ }
259
+ }
260
+ l = ranges::lower_bound(walls, arr[i].first) - walls.begin();
261
+ r = ranges::lower_bound(walls, right + 1) - walls.begin();
262
+ ans = max(ans, dfs(i - 1, 1) + (r - l));
263
+
264
+ return f[i][j] = ans;
265
+ };
266
+
267
+ return dfs(n - 1, 1);
268
+ }
269
+ };
124
270
```
125
271
126
272
#### Go
127
273
128
274
``` go
275
+ func maxWalls (robots []int , distance []int , walls []int ) int {
276
+ type pair struct {
277
+ x, d int
278
+ }
279
+ n := len (robots)
280
+ arr := make ([]pair, n)
281
+ for i := 0 ; i < n; i++ {
282
+ arr[i] = pair{robots[i], distance[i]}
283
+ }
284
+ sort.Slice (arr, func (i, j int ) bool {
285
+ return arr[i].x < arr[j].x
286
+ })
287
+ sort.Ints (walls)
288
+
289
+ f := make (map [[2 ]int ]int )
290
+
291
+ var dfs func (int , int ) int
292
+ dfs = func (i, j int ) int {
293
+ if i < 0 {
294
+ return 0
295
+ }
296
+ key := [2 ]int {i, j}
297
+ if v , ok := f[key]; ok {
298
+ return v
299
+ }
300
+
301
+ left := arr[i].x - arr[i].d
302
+ if i > 0 {
303
+ left = max (left, arr[i-1 ].x +1 )
304
+ }
305
+ l := sort.SearchInts (walls, left)
306
+ r := sort.SearchInts (walls, arr[i].x +1 )
307
+ ans := dfs (i-1 , 0 ) + (r - l)
308
+
309
+ right := arr[i].x + arr[i].d
310
+ if i+1 < n {
311
+ if j == 0 {
312
+ right = min (right, arr[i+1 ].x -arr[i+1 ].d -1 )
313
+ } else {
314
+ right = min (right, arr[i+1 ].x -1 )
315
+ }
316
+ }
317
+ l = sort.SearchInts (walls, arr[i].x )
318
+ r = sort.SearchInts (walls, right+1 )
319
+ ans = max (ans, dfs (i-1 , 1 )+(r-l))
320
+
321
+ f[key] = ans
322
+ return ans
323
+ }
324
+
325
+ return dfs (n-1 , 1 )
326
+ }
327
+ ```
129
328
329
+ #### TypeScript
330
+
331
+ ``` ts
332
+ function maxWalls(robots : number [], distance : number [], walls : number []): number {
333
+ type Pair = [number , number ];
334
+ const n = robots .length ;
335
+ const arr: Pair [] = robots .map ((r , i ) => [r , distance [i ]]);
336
+
337
+ _ .sortBy (arr , p => p [0 ]).forEach ((p , i ) => (arr [i ] = p ));
338
+ walls .sort ((a , b ) => a - b );
339
+ const f: number [][] = Array .from ({ length: n }, () => Array (2 ).fill (- 1 ));
340
+
341
+ function dfs(i : number , j : number ): number {
342
+ if (i < 0 ) {
343
+ return 0 ;
344
+ }
345
+ if (f [i ][j ] !== - 1 ) {
346
+ return f [i ][j ];
347
+ }
348
+
349
+ let left = arr [i ][0 ] - arr [i ][1 ];
350
+ if (i > 0 ) left = Math .max (left , arr [i - 1 ][0 ] + 1 );
351
+ let l = _ .sortedIndex (walls , left );
352
+ let r = _ .sortedIndex (walls , arr [i ][0 ] + 1 );
353
+ let ans = dfs (i - 1 , 0 ) + (r - l );
354
+
355
+ let right = arr [i ][0 ] + arr [i ][1 ];
356
+ if (i + 1 < n ) {
357
+ if (j === 0 ) {
358
+ right = Math .min (right , arr [i + 1 ][0 ] - arr [i + 1 ][1 ] - 1 );
359
+ } else {
360
+ right = Math .min (right , arr [i + 1 ][0 ] - 1 );
361
+ }
362
+ }
363
+ l = _ .sortedIndex (walls , arr [i ][0 ]);
364
+ r = _ .sortedIndex (walls , right + 1 );
365
+ ans = Math .max (ans , dfs (i - 1 , 1 ) + (r - l ));
366
+
367
+ f [i ][j ] = ans ;
368
+ return ans ;
369
+ }
370
+
371
+ return dfs (n - 1 , 1 );
372
+ }
130
373
```
131
374
132
375
<!-- tabs:end -->
0 commit comments