矩阵中的路径

题目描述:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。

 

例如:[ [a b c e]

             [s f c s]

             [a d e e] ]

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

分析:在力扣上看到一个我可以理解的题解,但是还不会实现,先把思路放在这。

1. 既然要在矩阵中匹配一个单词 word,那么我们自然地想到,应该先遍历矩阵找到单词的开头。

2. 找到开头后,有必要深入下去尝试匹配剩余字符。

3. 深入匹配有 4 个方向可以选择,只要有 1 个方向匹配成功了,就说明找到了;只有 4 个方向都无法匹配出 word,才说明这个开头不合适,应该继续遍历矩阵找新的开头。

4. 找到新的开头,继续重复以上匹配过程。

5. 由于匹配过程不能使用已经用过的字符,所以应当标记匹配过的字符。原始的想法是借助一个和 board 同样大小的矩阵 boolean[][] visit = new boolean[r][c],r 表示 board 的行数,c 表示 board 的列数;

但是我们可以通过巧妙的方法,避免这个空间开销。具体方法是,如果我们已经访问过这个字符,那么先把这个字符赋值为一个矩阵中不可能存在的字符,比如 '#',就可以表示已访问过了。当这条路走不通了,恢复它本来的样子就可以了。(当然必须说明,这种取巧方法是靠运气的,因为题目并没有说明矩阵中字符的种类,只是恰好用到了一个测试案例里没有的字符作为标记)为什么要恢复本来的样子?因为当前路走不通,只是因为开头不对。找到新的开头后,以前旧的开头访问过的字符对于新开头来说仍然是可以访问的。比如说,在以下矩阵匹配 word = "aabc"。

word = "abc"

board = [
    ['a', 'a'],
    ['c', 'b']
]

第一次从(0,0)开始匹配,标记为已访问
board = [
    ['#', 'a'],
    ['c', 'b']
]
由于4个方向都不能匹配完 word,因此从这个开头出发是匹配不出 word 的,删除标记,恢复本来的样子
board = [
    ['a', 'a'],
    ['c', 'b']
]
第二次从(0,1)开始匹配,是可以匹配出 "aacb" 的:(0,1) -> (0,0) -> (1,0) -> (1,1)
如果第一次匹配没有撤销标记,那么(0,0)位置上是'#'是不可走的,这将导致第二次匹配失败,而理应是成功的
 1 public class Solution {
 2     public boolean hasPath(char[] matrix, int rows, int cols, char[] str){
 3         int[] flag = new int[rows * cols];
 4         for(int i = 0; i < rows; i++) {
 5             for(int j = 0; j < cols; j++) {
 6                 if(help(matrix, rows, cols, str, 0, flag, i, j)) {
 7                     return true;
 8                 }
 9             }
10         }
11             
12         return false;
13     }
14     public boolean help(char[] matrix, int rows, int cols, char[] str, int cur, int[] flag, int r, int c){
15         // int row, int col 表明当前的坐标的行列值
16         // flag 表明那些曾经在路径中出现过的节点的坐标
17         // cur 表示当前需要匹配的字符的位置,是下一个待访问的节点,不需关系其有效性,因为最后一个元素是‘、0’
18         int index = cols * r + c;
19         if (r >= 0 && r < rows && c >= 0 && c < cols && flag[index] == 0) {
20             if (matrix[index] == str[cur]) {
21                 cur = cur + 1;
22                 if (cur >= str.length) return true;
23                     flag[index] = 1;
24                     if (help(matrix, rows, cols, str, cur, flag, r - 1, c) ||
25                             help(matrix, rows, cols, str, cur, flag, r + 1, c) ||
26                             help(matrix, rows, cols, str, cur, flag, r, c - 1) ||
27                             help(matrix, rows, cols, str, cur, flag, r, c + 1))
28                         return true;
29                     flag[index] = 0;
30                     return false;
31                 }
32                 return false;
33             }
34             return false;
35         }
36 }

 

posted on 2020-09-08 15:24  _那些你很冒险的梦  阅读(251)  评论(0)    收藏  举报

导航