剑指 Offer 12. 矩阵中的路径

 

 

 

 

 

 https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/

 

一、题解思路分析

  1.  思路和走迷宫的思路类似,需要采用递归+回溯的思路。即在当前点的上、下、左、右四个方向开始搜寻,会出现两种情况:第一种情况:搜寻到与字符串word相匹配的元素,则将word的指针向后移动一位,将函数中的各自坐标按照相应的方向发生改变,继续递归调用当前函数;第二种情况:搜寻了四个方向后,均与当前word指针位指向的元素不相等,则回溯。
  2. 在进行编写回溯相关的代码时,有一点非常需要注意!在之前的错误答案中,自己在进行递归调用时,直接return 一个方向的递归结果,这样会使得一个方向搜寻失败,之前的已经匹配成功的部分全部return false!正确的做法应该是return 四个方向搜寻结果的并集,这样只要有一个方向成功,仍然可以按照这个方向继续搜寻下去。
  3.     boolean recursion(char[][] board, String word, int i, int j, int index) {
            if (index == word.length()) return true;
            if (j + 1 < board[0].length && board[i][j + 1] == word.charAt(index)) {
                return recursion(board, word, i, j + 1, index + 1);
            } else if (i + 1 < board.length && board[i + 1][j] == word.charAt(index)) {
                return recursion(board, word, i + 1, j, index + 1);
            } else if (j - 1 >= 0 && board[i][j - 1] == word.charAt(index)) {
                return recursion(board, word, i, j - 1, index + 1);
            } else if (i - 1 >= 0 && board[i - 1][j] == word.charAt(index)) {
                return recursion(board, word, i - 1, j, index + 1);
            }
            return false;
        }

     


     

    既然提到需要使用递归,就必须考虑递归的终止条件。递归终止有两种情况,一种是寻找路径成功,即字符串word的指针已经超过其最后一位,这说明之前的字符全部匹配成功,此时只需要直接return true即可;还有一种情况是寻找路径失败,包括:寻找四个方向全部与字符不匹配、寻找越界仍未找到。

  4. 在进行路径搜寻时,还有一点要注意。已经访问过的节点是不可以再被访问的,所以还需要维护一个visited数组,当搜寻到已经访问过的节点时,需要return false。值得注意的是,当一条路径搜寻失败进行回溯时,需要释放这些节点,将其再重置为未访问过的状态,以免干扰其他路径搜寻到此节点。

 附上代码

 

 1 class Solution {
 2     public boolean exist(char[][] board, String word) {
 3         boolean[][] visited = new boolean[board.length][board[0].length];
 4         for (int i = 0; i < board.length; ++i) {
 5             for (int j = 0; j < board[0].length; ++j) {
 6                 if (dfs(i, j, board, word,visited,0)){
 7                     return true;
 8                 }
 9             }
10         }
11         return false;
12     }
13 
14     private boolean dfs(int x, int y, char[][] board, String word, boolean[][] visited,int index) {
15         if (x < 0 || y < 0 || x > board.length - 1 || y > board[0].length - 1||visited[x][y] == true||board[x][y]!=word.charAt(index)) {
16             return false;
17         }//返回false的终止条件
18         if (index==word.length()-1){//返回true的终止条件
19             return true;
20         }
21         visited[x][y] = true;
22         boolean flag = dfs(x+1, y,board,word,visited,index+1)||dfs(x, y+1,board,word,visited,index+1)||dfs(x-1, y,board,word,visited,index+1)||dfs(x, y-1,board,word,visited,index+1);
23         visited[x][y] = false;
24         return flag;
25     }
26 }

 

posted @ 2022-01-18 14:42  raindance1024  阅读(35)  评论(0)    收藏  举报