Skip to content

Commit 634ac4f

Browse files
committed
feat: add solutions to lcof problem: No.12
1 parent e245742 commit 634ac4f

File tree

5 files changed

+152
-108
lines changed

5 files changed

+152
-108
lines changed

lcof/面试题12. 矩阵中的路径/README.md

Lines changed: 97 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,19 @@
4444

4545
## 解法
4646

47-
深度优先搜索 DFS 解决。
47+
**方法一:枚举 + DFS**
48+
49+
我们可以枚举矩阵的每个位置 $(i, j)$,以该位置为起点,采用深度优先搜索的方法寻找字符串 `word` 的路径。如果找到了一条路径,即可返回 `true`,否则在枚举完所有的位置后,返回 `false`
50+
51+
那么问题的转换为如何采用深度优先搜索的方法寻找字符串 `word` 的路径。我们可以设计一个函数 $dfs(i, j, k)$,表示从位置 $(i, j)$ 开始,且当前将要匹配的字符为 `word[k]` 的情况下,是否能够找到字符串 `word` 的路径。如果能找到,返回 `true`,否则返回 `false`
52+
53+
函数 $dfs(i, j, k)$ 的执行流程如下:
54+
55+
- 如果当前字符 `word[k]` 已经匹配到字符串 `word` 的末尾,说明已经找到了字符串 `word` 的路径,返回 `true`
56+
- 如果当前位置 $(i, j)$ 超出矩阵边界,或者当前位置的字符与 `word[k]` 不同,说明当前位置不在字符串 `word` 的路径上,返回 `false`
57+
- 否则,我们将当前位置的字符标记为已访问(防止重复搜索),然后分别向当前位置的上、下、左、右四个方向继续匹配字符 `word[k + 1]`,只要有一条路径能够匹配到字符串 `word` 的路径,就说明能够找到字符串 `word` 的路径,返回 `true`。在回溯时,我们要将当前位置的字符还原为未访问过的状态。
58+
59+
时间复杂度 $O(m \times n \times 3^k)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为矩阵的行数和列数,而 $k$ 为字符串 `word` 的长度。我们需要枚举矩阵中的每个位置,然后对于每个位置,我们最多需要搜索三个方向。
4860

4961
<!-- tabs:start -->
5062

@@ -56,12 +68,11 @@ class Solution:
5668
def dfs(i, j, k):
5769
if k == len(word):
5870
return True
59-
if i < 0 or i >= m or j < 0 or j >= n or word[k] != board[i][j]:
71+
if i < 0 or i >= m or j < 0 or j >= n or board[i][j] != word[k]:
6072
return False
61-
board[i][j] = ''
62-
ans = any(
63-
dfs(i + a, j + b, k + 1) for a, b in [[0, -1], [0, 1], [1, 0], [-1, 0]]
64-
)
73+
board[i][j] = ""
74+
dirs = (-1, 0, 1, 0, -1)
75+
ans = any(dfs(i + a, j + b, k + 1) for a, b in pairwise(dirs))
6576
board[i][j] = word[k]
6677
return ans
6778

@@ -112,41 +123,38 @@ class Solution {
112123
}
113124
```
114125

115-
### **JavaScript**
126+
### **C++**
116127

117-
```js
118-
/**
119-
* @param {character[][]} board
120-
* @param {string} word
121-
* @return {boolean}
122-
*/
123-
var exist = function (board, word) {
124-
const m = board.length;
125-
const n = board[0].length;
126-
let dfs = function (i, j, k) {
127-
if (k == word.length) {
128-
return true;
129-
}
130-
if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != word[k]) {
131-
return false;
132-
}
133-
board[i][j] = ' ';
134-
let ans = false;
135-
let dirs = [-1, 0, 1, 0, -1];
136-
for (let l = 0; l < 4; ++l) {
137-
ans = ans || dfs(i + dirs[l], j + dirs[l + 1], k + 1);
138-
}
139-
board[i][j] = word[k];
140-
return ans;
141-
};
142-
for (let i = 0; i < m; ++i) {
143-
for (let j = 0; j < n; ++j) {
144-
if (dfs(i, j, 0)) {
128+
```cpp
129+
class Solution {
130+
public:
131+
bool exist(vector<vector<char>>& board, string word) {
132+
int m = board.size(), n = board[0].size();
133+
int dirs[5] = {-1, 0, 1, 0, -1};
134+
function<bool(int, int, int)> dfs = [&](int i, int j, int k) -> bool {
135+
if (k == word.size()) {
145136
return true;
146137
}
138+
if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != word[k]) {
139+
return false;
140+
}
141+
board[i][j] = '.';
142+
bool ans = 0;
143+
for (int l = 0; l < 4; ++l) {
144+
ans |= dfs(i + dirs[l], j + dirs[l + 1], k + 1);
145+
}
146+
board[i][j] = word[k];
147+
return ans;
148+
};
149+
for (int i = 0; i < m; ++i) {
150+
for (int j = 0; j < n; ++j) {
151+
if (dfs(i, j, 0)) {
152+
return true;
153+
}
154+
}
147155
}
156+
return false;
148157
}
149-
return false;
150158
};
151159
```
152160
@@ -183,30 +191,41 @@ func exist(board [][]byte, word string) bool {
183191
}
184192
```
185193

186-
### **C++**
187-
188-
```cpp
189-
class Solution {
190-
public:
191-
bool exist(vector<vector<char>>& board, string word) {
192-
for (int i = 0; i < board.size(); ++i)
193-
for (int j = 0; j < board[0].size(); ++j)
194-
if (dfs(i, j, 0, board, word))
195-
return 1;
196-
return 0;
197-
}
194+
### **JavaScript**
198195

199-
bool dfs(int i, int j, int k, vector<vector<char>>& board, string word) {
200-
if (k == word.size()) return 1;
201-
if (i < 0 || i >= board.size() || j < 0 || j >= board[0].size() || board[i][j] != word[k]) return 0;
202-
vector<int> dirs = {-1, 0, 1, 0, -1};
196+
```js
197+
/**
198+
* @param {character[][]} board
199+
* @param {string} word
200+
* @return {boolean}
201+
*/
202+
var exist = function (board, word) {
203+
const m = board.length;
204+
const n = board[0].length;
205+
const dirs = [-1, 0, 1, 0, -1];
206+
const dfs = (i, j, k) => {
207+
if (k == word.length) {
208+
return true;
209+
}
210+
if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != word[k]) {
211+
return false;
212+
}
203213
board[i][j] = ' ';
204-
bool ans = 0;
205-
for (int l = 0; l < 4; ++l)
206-
ans = ans || dfs(i + dirs[l], j + dirs[l + 1], k + 1, board, word);
214+
let ans = false;
215+
for (let l = 0; l < 4; ++l) {
216+
ans = ans || dfs(i + dirs[l], j + dirs[l + 1], k + 1);
217+
}
207218
board[i][j] = word[k];
208219
return ans;
220+
};
221+
for (let i = 0; i < m; ++i) {
222+
for (let j = 0; j < n; ++j) {
223+
if (dfs(i, j, 0)) {
224+
return true;
225+
}
226+
}
209227
}
228+
return false;
210229
};
211230
```
212231

@@ -292,32 +311,41 @@ impl Solution {
292311

293312
```cs
294313
public class Solution {
314+
private char[][] board;
315+
private string word;
316+
private int m;
317+
private int n;
318+
295319
public bool Exist(char[][] board, string word) {
296-
int k = 0;
297-
for (int i = 0; i < board.Length; i++)
298-
{
299-
for (int j = 0; j < board[0].Length; j++)
300-
{
301-
if (dfs(board, word, i, j, k)) {
320+
m = board.Length;
321+
n = board[0].Length;
322+
this.board = board;
323+
this.word = word;
324+
for (int i = 0; i < m; ++i) {
325+
for (int j = 0; j < n; ++j) {
326+
if (dfs(i, j, 0)) {
302327
return true;
303328
}
304329
}
305330
}
306331
return false;
307332
}
308333

309-
public bool dfs(char[][] board, string word, int i, int j, int k) {
310-
if (i > board.Length - 1 || i < 0 || j > board[0].Length - 1 || j < 0 || board[i][j] != word[k]) {
334+
private bool dfs(int i, int j, int k) {
335+
if (k == word.Length) {
336+
return true;
337+
}
338+
if (i < 0 || i >= m || j < 0 || j >= n || word[k] != board[i][j]) {
311339
return false;
312340
}
313-
if (k == word.Length - 1) {
314-
return true;
341+
board[i][j] = ' ';
342+
int[] dirs = {-1, 0, 1, 0, -1};
343+
bool ans = false;
344+
for (int l = 0; l < 4; ++l) {
345+
ans = ans || dfs(i + dirs[l], j + dirs[l + 1], k + 1);
315346
}
316-
317-
board[i][j] = '\0';
318-
bool res = dfs(board, word, i+1, j, k+1) || dfs(board, word, i, j+1, k+1) || dfs(board, word, i-1, j, k+1) || dfs(board, word, i, j-1, k+1);
319347
board[i][j] = word[k];
320-
return res;
348+
return ans;
321349
}
322350
}
323351
```
Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
11
class Solution {
22
public:
33
bool exist(vector<vector<char>>& board, string word) {
4-
for (int i = 0; i < board.size(); ++i)
5-
for (int j = 0; j < board[0].size(); ++j)
6-
if (dfs(i, j, 0, board, word))
7-
return 1;
8-
return 0;
9-
}
10-
11-
bool dfs(int i, int j, int k, vector<vector<char>>& board, string word) {
12-
if (k == word.size()) return 1;
13-
if (i < 0 || i >= board.size() || j < 0 || j >= board[0].size() || board[i][j] != word[k]) return 0;
14-
vector<int> dirs = {-1, 0, 1, 0, -1};
15-
board[i][j] = ' ';
16-
bool ans = 0;
17-
for (int l = 0; l < 4; ++l)
18-
ans = ans || dfs(i + dirs[l], j + dirs[l + 1], k + 1, board, word);
19-
board[i][j] = word[k];
20-
return ans;
4+
int m = board.size(), n = board[0].size();
5+
int dirs[5] = {-1, 0, 1, 0, -1};
6+
function<bool(int, int, int)> dfs = [&](int i, int j, int k) -> bool {
7+
if (k == word.size()) {
8+
return true;
9+
}
10+
if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != word[k]) {
11+
return false;
12+
}
13+
board[i][j] = '.';
14+
bool ans = 0;
15+
for (int l = 0; l < 4; ++l) {
16+
ans |= dfs(i + dirs[l], j + dirs[l + 1], k + 1);
17+
}
18+
board[i][j] = word[k];
19+
return ans;
20+
};
21+
for (int i = 0; i < m; ++i) {
22+
for (int j = 0; j < n; ++j) {
23+
if (dfs(i, j, 0)) {
24+
return true;
25+
}
26+
}
27+
}
28+
return false;
2129
}
2230
};
Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,38 @@
11
public class Solution {
2+
private char[][] board;
3+
private string word;
4+
private int m;
5+
private int n;
6+
27
public bool Exist(char[][] board, string word) {
3-
int k = 0;
4-
for (int i = 0; i < board.Length; i++)
5-
{
6-
for (int j = 0; j < board[0].Length; j++)
7-
{
8-
if (dfs(board, word, i, j, k)) {
8+
m = board.Length;
9+
n = board[0].Length;
10+
this.board = board;
11+
this.word = word;
12+
for (int i = 0; i < m; ++i) {
13+
for (int j = 0; j < n; ++j) {
14+
if (dfs(i, j, 0)) {
915
return true;
10-
}
16+
}
1117
}
1218
}
1319
return false;
1420
}
1521

16-
public bool dfs(char[][] board, string word, int i, int j, int k) {
17-
if (i > board.Length - 1 || i < 0 || j > board[0].Length - 1 || j < 0 || board[i][j] != word[k]) {
22+
private bool dfs(int i, int j, int k) {
23+
if (k == word.Length) {
24+
return true;
25+
}
26+
if (i < 0 || i >= m || j < 0 || j >= n || word[k] != board[i][j]) {
1827
return false;
1928
}
20-
if (k == word.Length - 1) {
21-
return true;
29+
board[i][j] = ' ';
30+
int[] dirs = {-1, 0, 1, 0, -1};
31+
bool ans = false;
32+
for (int l = 0; l < 4; ++l) {
33+
ans = ans || dfs(i + dirs[l], j + dirs[l + 1], k + 1);
2234
}
23-
24-
board[i][j] = '\0';
25-
bool res = dfs(board, word, i+1, j, k+1) || dfs(board, word, i, j+1, k+1) || dfs(board, word, i-1, j, k+1) || dfs(board, word, i, j-1, k+1);
2635
board[i][j] = word[k];
27-
return res;
36+
return ans;
2837
}
2938
}

lcof/面试题12. 矩阵中的路径/Solution.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
var exist = function (board, word) {
77
const m = board.length;
88
const n = board[0].length;
9-
let dfs = function (i, j, k) {
9+
const dirs = [-1, 0, 1, 0, -1];
10+
const dfs = (i, j, k) => {
1011
if (k == word.length) {
1112
return true;
1213
}
@@ -15,7 +16,6 @@ var exist = function (board, word) {
1516
}
1617
board[i][j] = ' ';
1718
let ans = false;
18-
let dirs = [-1, 0, 1, 0, -1];
1919
for (let l = 0; l < 4; ++l) {
2020
ans = ans || dfs(i + dirs[l], j + dirs[l + 1], k + 1);
2121
}

lcof/面试题12. 矩阵中的路径/Solution.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@ def exist(self, board: List[List[str]], word: str) -> bool:
33
def dfs(i, j, k):
44
if k == len(word):
55
return True
6-
if i < 0 or i >= m or j < 0 or j >= n or word[k] != board[i][j]:
6+
if i < 0 or i >= m or j < 0 or j >= n or board[i][j] != word[k]:
77
return False
8-
board[i][j] = ''
9-
ans = any(
10-
dfs(i + a, j + b, k + 1) for a, b in [[0, -1], [0, 1], [1, 0], [-1, 0]]
11-
)
8+
board[i][j] = ""
9+
dirs = (-1, 0, 1, 0, -1)
10+
ans = any(dfs(i + a, j + b, k + 1) for a, b in pairwise(dirs))
1211
board[i][j] = word[k]
1312
return ans
1413

0 commit comments

Comments
 (0)