Bootstrap

剑指 Offer 12. 矩阵中的路径 DFS回溯法

剑指 Offer 12. 矩阵中的路径

难度:中等
题目描述
在这里插入图片描述
解题思路
题目给的标签是动态规划,然后就一直顺着动态规划的思路想了好久,还是觉得不对啊,这不就是图的搜索嘛,动态规划感觉不好做。用dfs回溯感觉清晰很多
参考题解:面试题12. 矩阵中的路径(深度优先搜索 DFS ,清晰图解)
在这里插入图片描述
找到一个等于目标值的开始搜索,每次搜索上下左右四个相邻方向,剪枝条件是下标越界或者不等于目标值,当整个单词都匹配完的时候返回true;
要注意的是,回溯法在设置完状态,然后递归之后,还要状态回溯,清楚这一步标记的状态

/*
			  * 剑指 Offer 12. 矩阵中的路径
			  * 2020/7/18  dfs回溯法
			  */
			 public boolean exist(char[][] board, String word) {
				 int m = board.length;
				 int n = board[0].length;
				 boolean[][] visit = 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)) { //找到起点,开始搜索
							if(dfsExist(board,word,i,j,0,m,n,visit)) //进行dfs搜索
								return true;
						}
					}
				}
				 return false;
			    }
			 
			 public boolean dfsExist(char[][] board,String word,int i,int j,int index,int m ,int n,boolean visit[][]) {
				 if(index == word.length())  //如果匹配完了整个单词
					 return true;
				 
				 if(i >= m || i < 0 || j >= n || j < 0 || visit[i][j] || board[i][j] != word.charAt(index))
					 return false;
				 
				visit[i][j] = true;  //记录已经访问
				 
				boolean re =  dfsExist(board, word, i+1, j, index+1, m, n,visit) 
						 || dfsExist(board, word, i-1, j, index+1, m, n,visit)
						 || dfsExist(board, word, i, j+1, index+1, m, n,visit)
						 || dfsExist(board, word, i, j-1, index+1, m, n,visit);
				
				if(re) {
					return true;
				}else {
					visit[i][j] = false;
					return false;
				}
				 
			 }
		

在这里插入图片描述

可以优化的地方是直接用原数组来标记是不是已经访问过,访问的时候设置成一个特殊字符,回溯的时候设置回去。

public boolean exist(char[][] board, String word) {
				 int m = board.length;
				 int n = board[0].length;
				 for (int i = 0; i < m; i++) {
					for (int j = 0; j < n; j++) {
						if(board[i][j] == word.charAt(0)) { //找到起点,开始搜索
							if(dfsExist(board,word,i,j,0,m,n)) //进行dfs搜索
								return true;
						}
					}
				}
				 return false;
			    }
			 
			 public boolean dfsExist(char[][] board,String word,int i,int j,int index,int m ,int n) {
				 if(index == word.length())  //如果匹配完了整个单词
					 return true;
				 
				 if(i >= m || i < 0 || j >= n || j < 0 || board[i][j] == '#' || board[i][j] != word.charAt(index))
					 return false;
				
				 char temp = board[i][j];
				 board[i][j] = '#';  //记录已经访问
				 
				 boolean re =  dfsExist(board, word, i+1, j, index+1, m, n) 
						 || dfsExist(board, word, i-1, j, index+1, m, n)
						 || dfsExist(board, word, i, j+1, index+1, m, n)
						 || dfsExist(board, word, i, j-1, index+1, m, n);
				
				if(re) {
					return true;
				}else {
					board[i][j] = temp;
					return false;
				}
				 
			 }
;