判斷在一個矩陣中是否存在一條包含某字符串全部字符的路徑。路徑能夠從矩陣中的任意一個格子開始,每一步能夠在矩陣中向上下左右移動一個格子。若是一條路徑通過了矩陣中的某一個格子,則該路徑不能再進入該格子。java
例以下面的矩陣包含了一條 bfce 路徑。數組
思路:
使用回溯法(backtracking)進行求解,它是一種暴力搜索方法,經過搜索全部可能的結果來求解問題。回溯法在一次搜索結束時須要進行回溯(回退),將這一次搜索過程當中設置的狀態進行清除,從而開始一次新的搜索過程。例以下圖示例中,從 f 開始,下一步有 4 種搜索可能,若是先搜索 b,須要將 b 標記爲已經使用,防止重複使用。在這一次搜索結束以後,須要將 b 的已經使用狀態清除,並搜索 c。code
基本思想:遞歸
0.根據給定數組,初始化一個標誌位數組,初始化爲false,表示未走過,true表示已經走過,不能走第二次索引
1.根據行數和列數,遍歷數組,先找到一個與 str 字符串的第一個元素相匹配的矩陣元素,進入 judge字符串
2.根據i和j先肯定一維數組的位置,由於給定的 matrix 是一個一維數組io
3.肯定遞歸終止條件:越界,當前找到的矩陣值不等於數組對應位置的值,已經走過的,這三類狀況,都直接 false,說明這條路不通class
4.若 k,就是待斷定的字符串 str 的索引已經判斷到了最後一位,此時說明是匹配成功的bfc
5.下面就是本題的精髓,遞歸不斷地尋找周圍四個格子是否符合條件,只要有一個格子符合條件,就繼續再找這個符合條件的格子的四周是否存在符合條件的格子,直到k到達末尾或者不知足遞歸條件就中止。搜索
6.走到這一步,說明本次是不成功的,咱們要還原一下標誌位數組 index 處的標誌位,進入下一輪的判斷。
public class Solution { public boolean hasPath(char[] matrix, int rows, int cols, char[] str) { //標誌位,初始化爲false boolean[] flag = new boolean[matrix.length]; for(int i=0;i<rows;i++){ for(int j=0;j<cols;j++){ //循環遍歷二維數組,找到起點等於str第一個元素的值,再遞歸判斷四周是否有符合條件的----回溯法 if(judge(matrix,i,j,rows,cols,flag,str,0)){ return true; } } } return false; } //judge(初始矩陣,索引行座標i,索引縱座標j,矩陣行數,矩陣列數,待判斷的字符串,字符串索引初始爲0即先判斷字符串的第一位) private boolean judge(char[] matrix,int i,int j,int rows,int cols,boolean[] flag,char[] str,int k){ //先根據i和j計算匹配的第一個元素轉爲一維數組的位置 int index = i*cols+j; //遞歸終止條件 if(i<0 || j<0 || i>=rows || j>=cols || matrix[index] != str[k] || flag[index] == true) return false; //若k已經到達str末尾了,說明以前的都已經匹配成功了,直接返回true便可 if(k == str.length-1) return true; //要走的第一個位置置爲true,表示已經走過了 flag[index] = true; //回溯,遞歸尋找,每次找到了就給k加一,找不到,還原 if(judge(matrix,i-1,j,rows,cols,flag,str,k+1) || judge(matrix,i+1,j,rows,cols,flag,str,k+1) || judge(matrix,i,j-1,rows,cols,flag,str,k+1) || judge(matrix,i,j+1,rows,cols,flag,str,k+1) ) { return true; } //走到這,說明這一條路不通,還原,再試其餘的路徑 flag[index] = false; return false; } }