【劍指Offer學習】【面試題66:矩陣中的路徑】


題目:請設計一個函數,用來推斷在一個矩陣中是否存在一條包括某字符串全部字符的路徑。路徑能夠從矩陣中隨意一格開始。每一步能夠在矩陣中間向左、右、上、下移動一格。假設一條路徑經過了矩陣的某一格,那么該路徑不能再次進入該格子。


舉例分析

  比如在以下的3*4的矩陣中包括一條字符串”bcced”的路徑。

但矩陣中不包括字符串“abcb”的路徑,因為字符串的第一個字符b占領了矩陣中的第一行第二格子之后,路徑不能再次進入這個格子。


a b c e
s f c s
a d e e

解題思路

  這是一個能夠用回朔法解決的典型題。首先,在矩陣中任選一個格子作為路徑的起點。假設矩陣中某個格子的字符為ch,那么這個格子不可能處在路徑上的第i個位置。假設路徑上的第i個字符不是ch。那么這個格子不可能處在路徑上的第i個位置。假設路徑上的第i個字符正好是ch。那么往相鄰的格子尋找路徑上的第i+1個字符。除在矩陣邊界上的格子之外,其它格子都有4個相鄰的格子。反復這個過程知道路徑上的全部字符都在矩陣中找到相應的位置。


  因為回朔法的遞歸特性,路徑能夠被開成一個棧。當在矩陣中定位了路徑中前n個字符的位置之后。在與第n個字符相應的格子的周圍都沒有找到第n+1個字符。這個時候僅僅要在路徑上回到第n-1個字符。又一次定位第n個字符。


  因為路徑不能反復進入矩陣的格子。還須要定義和字符矩陣大小一樣的布爾值矩陣,用來標識路徑是否已經進入每個格子。
當矩陣中坐標為(row,col)的格子和路徑字符串中下標為pathLength的字符一樣時。從4個相鄰的格子(row,col-1),(row-1,col),(row,col+1)以及(row+1,col)中去定位路徑字符串中下標為pathLength+1的字符。
  假設4個相鄰的格子都沒有匹配字符串中下標為pathLength+1的字符,表明當前路徑字符串中下標為pathLength的字符在矩陣中的定位不對,我們須要回到前一個字符(pathLength-1),然后又一次定位。
  一直反復這個過程,直到路徑字符串上全部字符都在矩陣中找到合適的位置

代碼實現

public class Test66 {
    /** * 題目:請設計一個函數。用來推斷在一個矩陣中是否存在一條包括某字符串全部字符的路徑。

* 路徑能夠從矩陣中隨意一格開始。每一步能夠在矩陣中間向左、右、上、下移動一格。

* 假設一條路徑經過了矩陣的某一格,那么該路徑不能再次進入該格子。 * * @param matrix 輸入矩陣 * @param rows 矩陣行數 * @param cols 矩陣列數 * @param str 要搜索的字符串 * @return 是否找到 true是。false否 */ public static boolean hasPath(char[] matrix, int rows, int cols, char[] str) { // 參數校驗 if (matrix == null || matrix.length != rows * cols || str == null || str.length < 1) { return false; } // 變量初始化 boolean[] visited = new boolean[rows * cols]; for (int i = 0; i < visited.length; i++) { visited[i] = false; } // 記錄結果的數組。 int[] pathLength = {0}; // 以每個點為起始進行搜索 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (hasPathCore(matrix, rows, cols, str, visited, i, j, pathLength)) { return true; } } } return false; } /** * 回溯搜索算法 * * @param matrix 輸入矩陣 * @param rows 矩陣行數 * @param cols 矩陣列數 * @param str 要搜索的字符串 * @param visited 訪問標記數組 * @param row 當前處理的行號 * @param col 當前處理的列號 * @param pathLength 已經處理的str中字符個數 * @return 是否找到 true是,false否 */ private static boolean hasPathCore(char[] matrix, int rows, int cols, char[] str, boolean[] visited, int row, int col, int[] pathLength) { if (pathLength[0] == str.length) { return true; } boolean hasPath = false; // 推斷位置是否合法 if (row >= 0 && row < rows && col >= 0 && col < cols && matrix[row * cols + col] == str[pathLength[0]] && !visited[row * cols + col]) { visited[row * cols + col] = true; pathLength[0]++; // 按左上右下進行回溯 hasPath = hasPathCore(matrix, rows, cols, str, visited, row, col - 1, pathLength) || hasPathCore(matrix, rows, cols, str, visited, row - 1, col, pathLength) || hasPathCore(matrix, rows, cols, str, visited, row, col + 1, pathLength) || hasPathCore(matrix, rows, cols, str, visited, row + 1, col, pathLength); if (!hasPath) { pathLength[0]--; visited[row * cols + col] = false; } } return hasPath; } public static void main(String[] args) { //ABCE //ABCCED //SFCS //ADEE System.out.println(hasPath("ABCESFCSADEE".toCharArray(), 3, 4, "ABCCED".toCharArray()) + "[true]");// true //ABCE //SEE //SFCS //ADEE System.out.println(hasPath("ABCESFCSADEE".toCharArray(), 3, 4, "SEE".toCharArray()) + "[true]");// true //ABCE //ABCB //SFCS //ADEE System.out.println(hasPath("ABCESFCSADEE".toCharArray(), 3, 4, "ABCB".toCharArray()) + "[false]");// false //ABCEHJIG //SLHECCEIDEJFGGFIE //SFCSLOPQ //ADEEMNOE //ADIDEJFM //VCEIFGGS System.out.println(hasPath("ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS".toCharArray(), 5, 8, "SLHECCEIDEJFGGFIE".toCharArray()) + "[true]");// true //ABCEHJIG //SGGFIECVAASABCEHJIGQEM //SFCSLOPQ // //ADEEMNOE //ADIDEJFM //VCEIFGGS System.out.println(hasPath("ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS".toCharArray(), 5, 8, "SGGFIECVAASABCEHJIGQEM".toCharArray()) + "[true]");// true //ABCEHJIG //SGGFIECVAASABCEEJIGOEM //SFCSLOPQ //ADEEMNOE //ADIDEJFM //VCEIFGGS System.out.println(hasPath("ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS".toCharArray(), 5, 8, "SGGFIECVAASABCEEJIGOEM".toCharArray()) + "[false]");// false //ABCEHJIG //SGGFIECVAASABCEHJIGQEMS //SFCSLOPQ //ADEEMNOE //ADIDEJFM //VCEIFGGS System.out.println(hasPath("ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS".toCharArray(), 5, 8, "SGGFIECVAASABCEHJIGQEMS".toCharArray()) + "[false]");// false //AAAA //AAAAAAAAAAAA //AAAA //AAAA System.out.println(hasPath("AAAAAAAAAAAA".toCharArray(), 3, 4, "AAAAAAAAAAAA".toCharArray()) + "[true]");// true //AAAA //AAAAAAAAAAAAA //AAAA //AAAA System.out.println(hasPath("AAAAAAAAAAAA".toCharArray(), 3, 4, "AAAAAAAAAAAAA".toCharArray()) + "[false]");// false } }

執行結果

這里寫圖片描寫敘述

特別說明

歡迎轉載,轉載請注明出處【http://blog.csdn.net/DERRANTCM/article/details/46887767


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM