|
2 | 2 | description: 剑指 Offer 06. 从尾到头打印链表
|
3 | 3 | ---
|
4 | 4 |
|
5 |
| -# OF6.矩阵中的路径 |
| 5 | +# OF12.矩阵中的路径 |
6 | 6 |
|
7 | 7 | ## 题目描述
|
8 | 8 |
|
9 | 9 | [题目地址](https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/)
|
10 | 10 |
|
11 | 11 | 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。
|
12 | 12 |
|
13 |
| -[["a","b","c","e"], |
14 |
| -["s","f","c","s"], |
15 |
| -["a","d","e","e"]] |
16 |
| - |
17 |
| -但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。 |
18 | 13 |
|
19 | 14 |
|
20 | 15 | ### **示例 1:**
|
21 | 16 |
|
| 17 | + |
| 18 | + |
22 | 19 | ```go
|
23 |
| -输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED" |
24 |
| -输出:true |
| 20 | +Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED" |
| 21 | +Output: true |
25 | 22 | ```
|
26 | 23 |
|
27 | 24 |
|
| 25 | + |
| 26 | +[https://assets.leetcode.com/uploads/2020/11/04/word-1.jpg](https://assets.leetcode.com/uploads/2020/11/04/word-1.jpg) |
| 27 | + |
28 | 28 | ```go
|
29 |
| -输入:board = [["a","b"],["c","d"]], word = "abcd" |
30 |
| -输出:false |
| 29 | +Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE" |
| 30 | +Output: true |
31 | 31 | ```
|
32 | 32 |
|
33 | 33 | ## 题解
|
34 | 34 |
|
35 |
| -### 思路1 : 递归 |
| 35 | +### 思路1 : 递归回朔 |
36 | 36 |
|
37 | 37 | 递归遍历
|
38 | 38 |
|
39 | 39 | **算法流程:**
|
40 | 40 |
|
41 |
| -1. **复杂度分析:** |
42 |
| -2. **时间复杂度**$$O(N)$$**:**遍历N次,递归 N 次 |
43 |
| -3. **空间复杂度**$$O(N)$$**:**递归 N 次,开辟 N 个栈空间 |
| 41 | +1. **复杂度分析:**循环遍历矩阵中每个元素,分别判断上线左右,但是走过的撸不能在走,所以只用看3个方向。 |
| 42 | +2. **时间复杂度**$$O(M*N*3^L)$$**:其中**遍其中M、N为矩阵的长宽,L为字符串的长度。 |
| 43 | +3. **空间复杂度**$$O(L)$$**:** |
44 | 44 |
|
45 | 45 | #### 代码
|
46 | 46 |
|
47 | 47 | {% tabs %}
|
48 | 48 | {% tab title="Go" %}
|
49 | 49 | ```go
|
50 |
| -func reversePrint(head *ListNode) []int { |
51 |
| - ans := make([]int, 0) |
52 |
| - if head == nil { |
53 |
| - return ans |
54 |
| - } |
55 |
| - ans = reversePrint(head.Next) |
56 |
| - ans = append(ans, head.Val) |
57 |
| - return ans |
| 50 | +func exist(board [][]byte, word string) bool { |
| 51 | + m, n := len(board), len(board[0]) |
| 52 | + for i := 0; i < m; i++ { |
| 53 | + for j := 0; j < n; j++ { |
| 54 | + //如果在数组中找得到第一个数,就执行下一步,否则返回false |
| 55 | + if dfs(board, i, j, word) { |
| 56 | + return true |
| 57 | + } |
| 58 | + } |
| 59 | + } |
| 60 | + return false |
| 61 | +} |
| 62 | +func dfs(board [][]byte, i, j int, word string) bool { |
| 63 | + //如果找到最后一个数,则返回true,搜索成功 |
| 64 | + if len(word) == 0 { |
| 65 | + return true |
| 66 | + } |
| 67 | + //i,j的约束条件 |
| 68 | + if i < 0 || j < 0 || i == len(board) || j == len(board[0]) { |
| 69 | + return false |
| 70 | + } |
| 71 | + |
| 72 | + //进入DFS深度优先搜索 |
| 73 | + //先把正在遍历的该值重新赋值,如果在该值的周围都搜索不到目标字符,则再把该值还原 |
| 74 | + //如果在数组中找到第一个字符,则进入下一个字符的查找 |
| 75 | + if board[i][j] == word[0] { |
| 76 | + temp := board[i][j] |
| 77 | + board[i][j] = ' ' |
| 78 | + //下面这个if语句,如果成功进入,说明找到该字符,然后进行下一个字符的搜索,直到所有的搜索都成功, |
| 79 | + //即k == len(word) - 1 的大小时,会返回true,进入该条件语句,然后返回函数true值。 |
| 80 | + if dfs(board, i, j+1, word[1:]) || |
| 81 | + dfs(board, i, j-1, word[1:]) || |
| 82 | + dfs(board, i+1, j, word[1:]) || |
| 83 | + dfs(board, i-1, j, word[1:]) { |
| 84 | + return true |
| 85 | + } else { |
| 86 | + //没有找到目标字符,还原之前重新赋值的board[i][j] |
| 87 | + board[i][j] = temp |
| 88 | + } |
| 89 | + } |
| 90 | + |
| 91 | + return false |
58 | 92 | }
|
59 | 93 | ```
|
60 | 94 | {% endtab %}
|
61 |
| -{% endtabs %} |
62 |
| - |
63 | 95 |
|
| 96 | +{% tab title="Python" %} |
| 97 | +```python |
| 98 | +class Solution: |
| 99 | + def exist(self, board: List[List[str]], word: str) -> bool: |
| 100 | + |
| 101 | + self.ROWS = len(board) |
| 102 | + self.COLS = len(board[0]) |
| 103 | + self.board = board |
| 104 | + self.directs = [(0, 1), (1, 0), (0, -1), (-1, 0)] |
| 105 | + |
| 106 | + # 依次从每个坐标递归检查 |
| 107 | + for row in range(self.ROWS): |
| 108 | + for col in range(self.COLS): |
| 109 | + if self.dfs(row, col, word): |
| 110 | + return True |
| 111 | + # 默认返回 False |
| 112 | + return False |
| 113 | + |
| 114 | + def dfs(self, row, col, suffix): |
| 115 | + # 递归终止条件 |
| 116 | + if len(suffix) == 0: |
| 117 | + return True |
| 118 | + # 进入回溯前,检查边界 |
| 119 | + if row < 0 or row == self.ROWS or col < 0 or col == self.COLS or self.board[row][col] != suffix[0]: |
| 120 | + return False |
| 121 | + self.board[row][col] = '#' |
| 122 | + # 检查 4 个方向 |
| 123 | + for rowOffset, colOffset in self.directs: |
| 124 | + if self.dfs(row + rowOffset, col + colOffset, suffix[1:]): |
| 125 | + return True |
| 126 | + self.board[row][col] = suffix[0] |
| 127 | + return False |
| 128 | +``` |
| 129 | +{% endtab %} |
| 130 | +{% endtabs %} |
64 | 131 |
|
65 | 132 | ## 总结
|
66 | 133 |
|
|
0 commit comments