原题链接:剑指Offer12:矩阵中的路径
-
M,N
分别为矩阵行列大小,K
为字符串word
长度。 -
时间复杂度
O(3KMN)
: 最差情况下,需要遍历矩阵中长度为 K 字符串的所有方案,时间复杂度为O(3K)
;矩阵中共有MN
个起点,时间复杂度为O(MN)
。方案数计算: 设字符串长度为K
,搜索中每个字符有上、下、左、右四个方向可以选择,舍弃回头(上个字符)的方向,剩下 3 种选择,因此方案数的复杂度为O(3^K)
. -
空间复杂度
O(K)
: 搜索过程中的递归深度不超过K
,因此系统因函数调用累计使用的栈空间占用O(K)
(因为函数返回后,系统调用的栈空间会释放)。最坏情况下K = MN
,递归深度为MN
,此时系统栈使用O(MN)
的额外空间。
Golang
package main
import "fmt"
func exist(board [][]byte, word string) bool {
n := len(board)
m := len(board[0])
var dfs func(i, j, k int) bool
dfs = func(i, j, k int) bool {
if i < 0 || i >= n || j < 0 || j >= m || board[i][j] != word[k] {
return false
}
if k == len(word)-1 {
return true
}
board[i][j] = ' '
res := dfs(i+1, j, k+1) || dfs(i-1, j, k+1) || dfs(i, j+1, k+1) || dfs(i, j-1, k+1)
board[i][j] = word[k]
return res
}
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
if dfs(i, j, 0) {
return true
}
}
}
return false
}
func main() {
board := [][]byte{{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}}
word := "ABED"
fmt.Println(exist(board, word))
}
Python
from typing import List
class Solution:
def exist(self, board: List[List[str]], word: str) -> bool:
n, m = len(board), len(board[0])
def dfs(i, j, k):
if not 0 <= i < n or not 0 <= j < m or board[i][j] != word[k]: return False
if k == len(word) - 1: return True
board[i][j] = " "
res = dfs(i + 1, j, k + 1) or dfs(i - 1, j, k + 1) or dfs(i, j + 1, k + 1) or dfs(i, j - 1, k + 1)
board[i][j] = word[k]
return res
for i in range(n):
for j in range(m):
if dfs(i, j, 0): return True
return False
if __name__ == "__main__":
board = [["A", "B", "C", "E"], ["S", "F", "C", "S"], ["A", "D", "E", "E"]]
word = "ABCCED"
solution = Solution()
print(solution.exist(board,word))
C#
public class Solution
{
private bool dfs(char[][] board, string word, int i, int j, int k, int n, int m)
{
if (i < 0 || i >= n || j < 0 || j >= m || board[i][j] != word[k]) {
return false;
}
if (k == word.Length - 1) {
return true;
}
board[i][j] = ' ';
bool res = dfs(board, word, i + 1, j, k + 1, n, m) || dfs(board, word, i - 1, j, k + 1, n, m) || dfs(board, word, i, j + 1, k + 1, n, m) || dfs(board, word, i, j - 1, k + 1, n, m);
board[i][j] = word[k];
return res;
}
public bool Exist(char[][] board, string word)
{
int n = board.Length;
int m = board[0].Length;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (dfs(board, word, i, j, 0, n, m)) {
return true;
}
}
}
return false;
}
}
class Program
{
static void Main(string[] args)
{
char[][] board = new char[3][];
board[0] = new char[] { 'A', 'B', 'C', 'E' };
board[1] = new char[] { 'S', 'F', 'C', 'S' };
board[2] = new char[] { 'A', 'D', 'E', 'E' };
string word = "ABCCED";
Solution solution = new Solution();
Console.WriteLine(solution.Exist(board, word));
}
}