@@ -101,32 +101,275 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3661.Ma
101101
102102<!-- solution:start -->
103103
104- ### 方法一
104+ ### 方法一:记忆化搜索
105105
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$ 分别是机器人和墙壁的数量。
107123
108124#### Python3
109125
110126``` 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 )
112155```
113156
114157#### Java
115158
116159``` 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+ }
118218```
119219
120220#### C++
121221
122222``` 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+ };
124270```
125271
126272#### Go
127273
128274``` 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+ ```
129328
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+ }
130373```
131374
132375<!-- tabs:end -->
0 commit comments