面试题12:矩阵中的路径

题目

  请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用下划线标出)。但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
 A B T G
 C F C S
 J D E H

思路

  首先对所整个矩阵遍历,找到第一个字符,然后向上下左右查找下一个字符,由于每个字符都是相同的判断方法(先判断当前字符是否相等,再向四周查找),因此采用递归函数。由于字符查找过后不能重复进入,所以还要定义一个与字符矩阵大小相同的布尔值矩阵,进入过的格子标记为true。如果不满足的情况下,需要进行回溯,此时,要将当前位置的布尔值标记回false。(所谓的回溯无非就是对使用过的字符进行标记和处理后的去标记)

测试用例

  1.功能测试(多行多列矩阵中存在或者不存在路径)

  2.边界值测试(矩阵只有一行;矩阵与路径的所有字符都相同)

  3.特殊输入测试(null)

  1 public class StringPathInMatrix {
  2     public boolean hasPath(char[] matrix, int rows, int cols, char[] str) {
  3         if (matrix == null || rows < 1 || cols < 1 || str == null) {
  4             return false;
  5         }
  6         boolean[] isVisited = new boolean[rows * cols];
  7 //        for (boolean v : isVisited) {
  8 //            v = false;
  9 //        }
 10         int pathLength = 0;
 11         for (int row = 0; row < rows; row++) {
 12             for (int col = 0; col < cols; col++) {
 13                 if (hasPathCore(matrix, rows, cols, row, col, str, pathLength, isVisited))
 14                     return true;
 15             }
 16         }
 17         return false;
 18     }
 19 /*
 20     str[pathLength] != matrix[row * cols + col])作用是比较 矩阵与目标矩阵是否存在对应关系
 21     isVisited[row * cols + col] == true作用是一条路径经过了矩阵的某一格,那么该路径不能再次进入该位置。
 22  */
 23     private boolean hasPathCore(char[] matrix, int rows, int cols, int row, int col, char[] str, int pathLength,
 24                                 boolean[] isVisited) {
 25         if (row < 0 || col < 0 || row >= rows || col >= cols || isVisited[row * cols + col] == true
 26                 || str[pathLength] != matrix[row * cols + col])
 27             return false;
 28         if (pathLength == str.length - 1)
 29             return true;
 30         boolean hasPath = false;
 31         isVisited[row * cols + col] = true;
 32         hasPath = hasPathCore(matrix, rows, cols, row - 1, col, str, pathLength + 1, isVisited)
 33                 || hasPathCore(matrix, rows, cols, row + 1, col, str, pathLength + 1, isVisited)
 34                 || hasPathCore(matrix, rows, cols, row, col - 1, str, pathLength + 1, isVisited)
 35                 || hasPathCore(matrix, rows, cols, row, col + 1, str, pathLength + 1, isVisited);
 36 
 37         if (!hasPath) {
 38             isVisited[row * cols + col] = false;
 39         }
 40         return hasPath;
 41     }
 42 
 43     // =======测试代码========
 44 
 45     // A B T G
 46     // C F C S
 47     // J D E H
 48 
 49     // BFCTB
 50     public void test1() {
 51         char[] matrix = "ABTGCFCSJDEH".toCharArray();
 52         int rows = 3;
 53         int cols = 4;
 54         char[] str = "BFCTB".toCharArray();
 55         if (!hasPath(matrix, rows, cols, str))
 56             System.out.println("Test1 passed.");
 57         else
 58             System.out.println("Test1 failed.");
 59     }
 60 
 61     // A B T G
 62     // C F C S
 63     // J D E H
 64 
 65     // BFCE
 66     public void test2() {
 67         char[] matrix = "ABTGCFCSJDEH".toCharArray();
 68         int rows = 3;
 69         int cols = 4;
 70         char[] str = "BFCE".toCharArray();
 71         if (hasPath(matrix, rows, cols, str))
 72             System.out.println("Test2 passed.");
 73         else
 74             System.out.println("Test2 failed.");
 75     }
 76 
 77     // matrix=null
 78     public void test3() {
 79         char[] matrix = null;
 80         int rows = 0;
 81         int cols = 0;
 82         char[] str = "BFCE".toCharArray();
 83         if (!hasPath(matrix, rows, cols, str))
 84             System.out.println("Test3 passed.");
 85         else
 86             System.out.println("Test3 failed.");
 87     }
 88 
 89     // str=null
 90     public void test4() {
 91         char[] matrix = "ABTGCFCSJDEH".toCharArray();
 92         int rows = 3;
 93         int cols = 4;
 94         char[] str = null;
 95         if (!hasPath(matrix, rows, cols, str))
 96             System.out.println("Test4 passed.");
 97         else
 98             System.out.println("Test4 failed.");
 99     }
100 
101     // A
102 
103     // A
104     public void test5() {
105         char[] matrix = "A".toCharArray();
106         int rows = 1;
107         int cols = 1;
108         char[] str = "A".toCharArray();
109         if (hasPath(matrix, rows, cols, str))
110             System.out.println("Test5 passed.");
111         else
112             System.out.println("Test5 failed.");
113     }
114 
115     // A
116 
117     // B
118     public void test6() {
119         char[] matrix = "A".toCharArray();
120         int rows = 1;
121         int cols = 1;
122         char[] str = "B".toCharArray();
123         if (!hasPath(matrix, rows, cols, str))
124             System.out.println("Test6 passed.");
125         else
126             System.out.println("Test6 failed.");
127     }
128 
129     // AAAA
130     // AAAA
131     // AAAA
132 
133     // AAAAAAAAAAAA
134     public void test7() {
135         char[] matrix = "AAAAAAAAAAAA".toCharArray();
136         int rows = 3;
137         int cols = 4;
138         char[] str = "AAAAAAAAAAAA".toCharArray();
139         if (hasPath(matrix, rows, cols, str))
140             System.out.println("Test7 passed.");
141         else
142             System.out.println("Test7 failed.");
143     }
144 
145     public static void main(String[] args) {
146         StringPathInMatrix demo = new StringPathInMatrix();
147         demo.test1();
148         demo.test2();
149         demo.test3();
150         demo.test4();
151         demo.test5();
152         demo.test6();
153         demo.test7();
154     }
155 }

收获

   1.回溯法用于多个步骤,每个步骤有多个选项的问题:若当前步骤满足条件,给定一个标记,当发现之后的步骤不满足条件时,去除标记。

  2.字符串转为字符数组,使用toCharArray()方法

  3.二维数组下标的计算:row*cols+col

posted @ 2019-09-19 11:00  超爱show  阅读(310)  评论(0编辑  收藏  举报