剑指 Offer 12. 矩阵中的路径
dfs+剪枝问题。
这里由于是需要对所有的相邻节点尝试并且如果行不通需要重试,所以还需要回溯,回溯的过程中也有需要剪枝的地方,如走过的地方就不能再走,并且不能走出图外去。
这里我们用isContains
表示这一轮的搜索是否搜到了要搜的字母,如果搜索到了,就继续往相邻的位置继续搜,如果没有搜到,要记得清除搜索痕迹并且重试。
class Solution { private static final int[] dx = new int[]{-1, 0, 1, 0}; private static final int[] dy = new int[]{0, -1, 0, 1}; public boolean exist(char[][] board, String word) { if(null == word || word.equals("")) { return true; } int m = board.length; int n = board[0].length; boolean[][] visted = new boolean[m][n]; for(int i = 0; i < m; i++) { for(int j = 0; j < n; j++) { if(board[i][j] == word.charAt(0)) { boolean isContains = backtrack(board, word, visted, 0, i, j); if(isContains) return true; } } } return false; } private boolean backtrack(char[][] board, String word, boolean[][] visted, int position, int x, int y) { visted[x][y] = true; if(position == word.length() - 1) { return true; } boolean isContains = false; for(int i = 0; i < 4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; int m = board.length; int n = board[0].length; if(nx < 0 || nx >= m || ny < 0 || ny >= n || visted[nx][ny] || board[nx][ny] != word.charAt(position + 1)) { continue; } else { visted[nx][ny] = true; isContains = backtrack(board, word, visted, position + 1, nx, ny); if(isContains) return true; visted[nx][ny] = false; } } if(!isContains) visted[x][y] = false; return isContains; } }