矩阵中的路径(Python and C++解法)

题目:

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。

[["a","b","c","e"],
[ "s","f","c","s"],
["a","d","e","e"]]

但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。

示例 1:

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true
示例 2:

输入:board = [["a","b"],["c","d"]], word = "abcd"
输出:false

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof

思路:

  采用回溯法,即DFS。当搜索到某一点之后,不考虑边界条件的情况下,其有上下左右四个方向继续递归搜索,但由于搜索过的点不能被再次搜索,实际上只有三个方向可以继续递归。

  最坏的情况下,每个点都要遍历三条递归路径的全部字符串,所以时间复杂度是3^k * i*j,且最坏情况下空间复杂度为k。

  搜索终止条件:行或列索引越界 或  当前矩阵元素(包括已经被标记为'\'的元素)与目标字符不同。

Python解法:

 1 class Solution:
 2     def exist(self, board: List[List[str]], word: str) -> bool:
 3         def dfs(i, j, k):
 4             if not 0 <= i < len(board) or not 0 <= j < len(board[0]) or board[i][j] != word[k]:  # 搜索终止条件
 5                 return False
 6             if k == len(word) - 1:  # 搜索成功条件
 7                 return True
 8 
 9             temp = board[i][j]  # 暂存当前搜索点
10             board[i][j] = '!'  # 标记已经被搜索
11             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)
12             board[i][j] = temp  # 还原矩阵元素,以备下一轮搜索使用
13             return res
14 
15         # 由于矩阵中可能存在重复的元素,因此每个元素都可能是起始点
16         for i in range(len(board)):  
17             for j in range(len(board[0])):
18                 if dfs(i, j, 0):
19                     return True
20         return False

C++解法:

 1 class Solution {
 2 public:
 3     bool exist(vector<vector<char>>& board, string word) {
 4         for(int m = 0; m < board.size(); m++)
 5             for(int n = 0; n < board[0].size(); n++)
 6                 if(dfs(board, word, m, n, 0))
 7                     return true;
 8         return false;
 9 
10 
11     }
12     bool dfs(vector<vector<char>> &b, string &w, int i, int j, int k) {
13         if(i < 0 || i >= b.size() || j < 0 || j >= b[0].size() || b[i][j] != w[k])
14         return false;
15         // 不可以按照python的写法:if(!(0 <= i < b.size()) || !(0 <= j < b[0].size()) || b[i][j] != w[k])
16         if(w.size()-1 == k)
17             return true;
18 
19         char temp = b[i][j];
20         b[i][j] = '!';
21         bool res = dfs(b,w,i+1,j,k+1) || dfs(b,w,i-1,j,k+1) || dfs(b,w,i,j+1,k+1) || dfs(b,w,i,j-1,k+1);
22         b[i][j] = temp;
23         return res;
24     }
25 };
posted @ 2020-06-30 16:27  孔子?孟子?小柱子!  阅读(292)  评论(0编辑  收藏  举报