53
53
54
54
<!-- 这里可写通用的实现逻辑 -->
55
55
56
- 回溯(深度优先搜索 DFS )实现。
56
+ ** 方法一:DFS(回溯)**
57
+
58
+ 我们可以枚举网格的每一个位置 $(i, j)$ 作为搜索的起点,然后从起点开始进行深度优先搜索,如果可以搜索到单词的末尾,就说明单词存在,否则说明单词不存在。
59
+
60
+ 因此,我们设计一个函数 $dfs(i, j, k)$,表示从网格的 $(i, j)$ 位置出发,且从单词的第 $k$ 个字符开始搜索,是否能够搜索成功。函数 $dfs(i, j, k)$ 的执行步骤如下:
61
+
62
+ - 如果 $k = |word|-1$,说明已经搜索到单词的最后一个字符,此时只需要判断网格 $(i, j)$ 位置的字符是否等于 $word[ k] $,如果相等则说明单词存在,否则说明单词不存在。无论单词是否存在,都无需继续往下搜索,因此直接返回结果。
63
+ - 否则,如果 $word[ k] $ 字符不等于网格 $(i, j)$ 位置的字符,说明本次搜索失败,直接返回 ` false ` 。
64
+ - 否则,我们将网格 $(i, j)$ 位置的字符暂存于 $c$ 中,然后将此位置的字符修改为一个特殊字符 ` '0' ` ,代表此位置的字符已经被使用过,防止之后搜索时重复使用。然后我们从 $(i, j)$ 位置的上、下、左、右四个方向分别出发,去搜索网格中第 $k+1$ 个字符,如果四个方向有任何一个方向搜索成功,就说明搜索成功,否则说明搜索失败,此时我们需要还原网格 $(i, j)$ 位置的字符,即把 $c$ 放回网格 $(i, j)$ 位置(回溯)。
65
+
66
+ 在主函数中,我们枚举网格中的每一个位置 $(i, j)$ 作为起点,如果调用 $dfs(i, j, 0)$ 返回 ` true ` ,就说明单词存在,否则说明单词不存在,返回 ` false ` 。
67
+
68
+ 时间复杂度 $O(m \times n \times 3^k)$,空间复杂度 $O(\min(m \times n, k))$。其中 $m$ 和 $n$ 分别是网格的行数和列数;而 $k$ 是字符串 $word$ 的长度。
57
69
58
70
<!-- tabs:start -->
59
71
64
76
``` python
65
77
class Solution :
66
78
def exist (self , board : List[List[str ]], word : str ) -> bool :
67
- def dfs (i , j , cur ):
68
- if cur == len (word):
69
- return True
70
- if (
71
- i < 0
72
- or i >= m
73
- or j < 0
74
- or j >= n
75
- or board[i][j] == ' 0'
76
- or word[cur] != board[i][j]
77
- ):
79
+ def dfs (i : int , j : int , k : int ) -> bool :
80
+ if k == len (word) - 1 :
81
+ return board[i][j] == word[k]
82
+ if board[i][j] != word[k]:
78
83
return False
79
- t = board[i][j]
80
- board[i][j] = ' 0 '
81
- for a, b in [[ 0 , 1 ], [ 0 , - 1 ], [ - 1 , 0 ], [ 1 , 0 ]] :
84
+ c = board[i][j]
85
+ board[i][j] = " 0 "
86
+ for a, b in pairwise(( - 1 , 0 , 1 , 0 , - 1 )) :
82
87
x, y = i + a, j + b
83
- if dfs(x, y, cur + 1 ):
88
+ ok = 0 <= x < m and 0 <= y < n and board[x][y] != " 0"
89
+ if ok and dfs(x, y, k + 1 ):
84
90
return True
85
- board[i][j] = t
91
+ board[i][j] = c
86
92
return False
87
93
88
94
m, n = len (board), len (board[0 ])
@@ -95,94 +101,45 @@ class Solution:
95
101
96
102
``` java
97
103
class Solution {
104
+ private int m;
105
+ private int n;
106
+ private String word;
107
+ private char [][] board;
108
+
98
109
public boolean exist (char [][] board , String word ) {
99
- int m = board. length;
100
- int n = board[0 ]. length;
110
+ m = board. length;
111
+ n = board[0 ]. length;
112
+ this . word = word;
113
+ this . board = board;
101
114
for (int i = 0 ; i < m; ++ i) {
102
115
for (int j = 0 ; j < n; ++ j) {
103
- if (dfs(i, j, 0 , m, n, board, word )) {
116
+ if (dfs(i, j, 0 )) {
104
117
return true ;
105
118
}
106
119
}
107
120
}
108
121
return false ;
109
122
}
110
123
111
- private boolean dfs (int i , int j , int cur , int m , int n , char [][] board , String word ) {
112
- if (cur == word. length()) {
113
- return true ;
124
+ private boolean dfs (int i , int j , int k ) {
125
+ if (k == word. length() - 1 ) {
126
+ return board[i][j] == word . charAt(k) ;
114
127
}
115
- if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != word. charAt(cur )) {
128
+ if (board[i][j] != word. charAt(k )) {
116
129
return false ;
117
130
}
118
- board[i][j] += 256 ;
131
+ char c = board[i][j];
132
+ board[i][j] = ' 0' ;
119
133
int [] dirs = {- 1 , 0 , 1 , 0 , - 1 };
120
- for (int k = 0 ; k < 4 ; ++ k) {
121
- int x = i + dirs[k];
122
- int y = j + dirs[k + 1 ];
123
- if (dfs(x, y, cur + 1 , m, n, board, word)) {
134
+ for (int u = 0 ; u < 4 ; ++ u) {
135
+ int x = i + dirs[u], y = j + dirs[u + 1 ];
136
+ if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] != ' 0' && dfs(x, y, k + 1 )) {
124
137
return true ;
125
138
}
126
139
}
127
- board[i][j] -= 256 ;
128
- return false ;
129
- }
130
- }
131
- ```
132
-
133
- ### ** TypeScript**
134
-
135
- ``` ts
136
- function exist(board : string [][], word : string ): boolean {
137
- let m = board .length ,
138
- n = board [0 ].length ;
139
- let visited = Array .from ({ length: m }, v => new Array (n ).fill (false ));
140
- for (let i = 0 ; i < m ; ++ i ) {
141
- for (let j = 0 ; j < n ; ++ j ) {
142
- if (dfs (board , word , i , j , 0 , visited )) {
143
- return true ;
144
- }
145
- }
146
- }
147
- return false ;
148
- }
149
-
150
- function dfs(
151
- board : string [][],
152
- word : string ,
153
- i : number ,
154
- j : number ,
155
- depth : number ,
156
- visited : boolean [][],
157
- ): boolean {
158
- let m = board .length ,
159
- n = board [0 ].length ;
160
- if (i < 0 || i > m - 1 || j < 0 || j > n - 1 || visited [i ][j ]) {
140
+ board[i][j] = c;
161
141
return false ;
162
142
}
163
- if (board [i ][j ] != word .charAt (depth )) {
164
- return false ;
165
- }
166
-
167
- if (depth == word .length - 1 ) {
168
- return true ;
169
- }
170
-
171
- visited [i ][j ] = true ;
172
- ++ depth ;
173
- let res = false ;
174
- for (let [dx, dy] of [
175
- [0 , 1 ],
176
- [0 , - 1 ],
177
- [1 , 0 ],
178
- [- 1 , 0 ],
179
- ]) {
180
- let x = i + dx ,
181
- y = j + dy ;
182
- res = res || dfs (board , word , x , y , depth , visited );
183
- }
184
- visited [i ][j ] = false ;
185
- return res ;
186
143
}
187
144
```
188
145
@@ -193,94 +150,60 @@ class Solution {
193
150
public:
194
151
bool exist(vector<vector<char >>& board, string word) {
195
152
int m = board.size(), n = board[ 0] .size();
196
- for (int i = 0; i < m; ++i)
197
- for (int j = 0; j < n; ++j)
198
- if (dfs(i, j, 0, m, n, board, word))
153
+ int dirs[ 5] = {-1, 0, 1, 0, -1};
154
+ function<bool(int, int, int)> dfs = [ &] (int i, int j, int k) -> bool {
155
+ if (k == word.size() - 1) {
156
+ return board[ i] [ j ] == word[ k] ;
157
+ }
158
+ if (board[ i] [ j ] != word[ k] ) {
159
+ return false;
160
+ }
161
+ char c = board[ i] [ j ] ;
162
+ board[ i] [ j ] = '0';
163
+ for (int u = 0; u < 4; ++u) {
164
+ int x = i + dirs[ u] , y = j + dirs[ u + 1] ;
165
+ if (x >= 0 && x < m && y >= 0 && y < n && board[ x] [ y ] != '0' && dfs(x, y, k + 1)) {
199
166
return true;
200
- return false;
201
- }
202
-
203
- bool dfs(int i, int j, int cur, int m, int n, vector<vector<char>>& board, string& word) {
204
- if (cur == word.size()) return true;
205
- if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != word[cur]) return false;
206
- char t = board[i][j];
207
- board[i][j] = '0';
208
- vector<int> dirs = {-1, 0, 1, 0, -1};
209
- for (int k = 0; k < 4; ++k) {
210
- int x = i + dirs[k], y = j + dirs[k + 1];
211
- if (dfs(x, y, cur + 1, m, n, board, word)) return true;
212
- }
213
- board[i][j] = t;
214
- return false ;
215
- }
216
- };
217
- ```
218
-
219
- ### ** C#**
220
-
221
- ``` cs
222
- public class Solution {
223
- public bool Exist (char [][] board , string word ) {
224
- var lenI = board .Length ;
225
- var lenJ = lenI == 0 ? 0 : board [0 ].Length ;
226
- var visited = new bool [lenI , lenJ ];
227
- for (var i = 0 ; i < lenI ; ++ i )
228
- {
229
- for (var j = 0 ; j < lenJ ; ++ j )
230
- {
231
- if (Search (board , visited , word , lenI , lenJ , i , j , 0 ))
232
- {
167
+ }
168
+ }
169
+ board[ i] [ j ] = c;
170
+ return false;
171
+ };
172
+ for (int i = 0; i < m; ++i) {
173
+ for (int j = 0; j < n; ++j) {
174
+ if (dfs(i, j, 0)) {
233
175
return true;
234
176
}
235
177
}
236
178
}
237
179
return false;
238
180
}
239
-
240
- private int [,] paths = new int [4 ,2 ] { { - 1 , 0 }, { 1 , 0 }, { 0 , - 1 }, { 0 , 1 } };
241
-
242
- private bool Search (char [][] board , bool [,] visited , string word , int lenI , int lenJ , int i , int j , int p )
243
- {
244
- if (p == word .Length )
245
- {
246
- return true ;
247
- }
248
- if (i < 0 || i >= lenI || j < 0 || j >= lenJ ) return false ;
249
- if (visited [i , j ] || word [p ] != board [i ][j ]) return false ;
250
- visited [i , j ] = true ;
251
- for (var k = 0 ; k < 4 ; ++ k )
252
- {
253
- if (Search (board , visited , word , lenI , lenJ , i + paths [k , 0 ], j + paths [k , 1 ], p + 1 )) return true ;
254
- }
255
- visited [i , j ] = false ;
256
- return false ;
257
- }
258
- }
181
+ };
259
182
```
260
183
261
184
### **Go**
262
185
263
186
```go
264
187
func exist(board [][]byte, word string) bool {
265
188
m, n := len(board), len(board[0])
266
- var dfs func (i, j, cur int ) bool
267
- dfs = func (i, j, cur int ) bool {
268
- if cur == len (word) {
269
- return true
189
+ var dfs func(int, int, int) bool
190
+ dfs = func(i, j, k int) bool {
191
+ if k == len(word)-1 {
192
+ return board[i][j] == word[k]
270
193
}
271
- if i < 0 || i >= m || j < 0 || j >= n || board[i][j] != word[cur ] {
194
+ if board[i][j] != word[k ] {
272
195
return false
273
196
}
274
- t := board[i][j]
197
+ dirs := [5]int{-1, 0, 1, 0, -1}
198
+ c := board[i][j]
275
199
board[i][j] = '0'
276
- dirs := []int {-1 , 0 , 1 , 0 , -1 }
277
- for k := 0 ; k < 4 ; k++ {
278
- x , y := i+dirs[k], j+dirs[k+1 ]
279
- if dfs (x, y, cur+1 ) {
200
+ for u := 0; u < 4; u++ {
201
+ x, y := i+dirs[u], j+dirs[u+1]
202
+ if x >= 0 && x < m && y >= 0 && y < n && board[x][y] != '0' && dfs(x, y, k+1) {
280
203
return true
281
204
}
282
205
}
283
- board[i][j] = t
206
+ board[i][j] = c
284
207
return false
285
208
}
286
209
for i := 0; i < m; i++ {
@@ -294,6 +217,89 @@ func exist(board [][]byte, word string) bool {
294
217
}
295
218
```
296
219
220
+ ### ** TypeScript**
221
+
222
+ ``` ts
223
+ function exist(board : string [][], word : string ): boolean {
224
+ const [m, n] = [board .length , board [0 ].length ];
225
+ const dirs = [- 1 , 0 , 1 , 0 , - 1 ];
226
+ const dfs = (i : number , j : number , k : number ): boolean => {
227
+ if (k === word .length - 1 ) {
228
+ return board [i ][j ] === word [k ];
229
+ }
230
+ if (board [i ][j ] !== word [k ]) {
231
+ return false ;
232
+ }
233
+ const c = board [i ][j ];
234
+ board [i ][j ] = ' 0' ;
235
+ for (let u = 0 ; u < 4 ; ++ u ) {
236
+ const [x, y] = [i + dirs [u ], j + dirs [u + 1 ]];
237
+ const ok = x >= 0 && x < m && y >= 0 && y < n ;
238
+ if (ok && board [x ][y ] !== ' 0' && dfs (x , y , k + 1 )) {
239
+ return true ;
240
+ }
241
+ }
242
+ board [i ][j ] = c ;
243
+ return false ;
244
+ };
245
+ for (let i = 0 ; i < m ; ++ i ) {
246
+ for (let j = 0 ; j < n ; ++ j ) {
247
+ if (dfs (i , j , 0 )) {
248
+ return true ;
249
+ }
250
+ }
251
+ }
252
+ return false ;
253
+ }
254
+ ```
255
+
256
+ ### ** C#**
257
+
258
+ ``` cs
259
+ public class Solution {
260
+ private int m ;
261
+ private int n ;
262
+ private char [][] board ;
263
+ private string word ;
264
+
265
+ public bool Exist (char [][] board , string word ) {
266
+ m = board .Length ;
267
+ n = board [0 ].Length ;
268
+ this .board = board ;
269
+ this .word = word ;
270
+ for (int i = 0 ; i < m ; ++ i ) {
271
+ for (int j = 0 ; j < n ; ++ j ) {
272
+ if (dfs (i , j , 0 )) {
273
+ return true ;
274
+ }
275
+ }
276
+ }
277
+ return false ;
278
+ }
279
+
280
+ private bool dfs (int i , int j , int k ) {
281
+ if (k == word .Length - 1 ) {
282
+ return board [i ][j ] == word [k ];
283
+ }
284
+ if (board [i ][j ] != word [k ]) {
285
+ return false ;
286
+ }
287
+ char c = board [i ][j ];
288
+ board [i ][j ] = '0' ;
289
+ int [] dirs = { - 1 , 0 , 1 , 0 , - 1 };
290
+ for (int u = 0 ; u < 4 ; ++ u ) {
291
+ int x = i + dirs [u ];
292
+ int y = j + dirs [u + 1 ];
293
+ if (x >= 0 && x < m && y >= 0 && y < n && board [x ][y ] != '0' && dfs (x , y , k + 1 )) {
294
+ return true ;
295
+ }
296
+ }
297
+ board [i ][j ] = c ;
298
+ return false ;
299
+ }
300
+ }
301
+ ```
302
+
297
303
### ** Rust**
298
304
299
305
``` rust
0 commit comments