【Java】面试题12:矩阵中的路径

面试题12:矩阵中的路径

题目:
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 a b t g c f c s j d e h 矩阵中包含一条字符串”bfce”的路径,但是矩阵中不包含”abfb”路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

a b t g
c f c s
j d e h
这题典型的回溯法,当前位置能不能走,要看后面的路径是否满足条件,当上下左右都不能走时,说明该位置不能走,要回退一步,如果回退到出发点,说明这个点作为起点行不通。

【解题思路】

这是一个可以用回朔法解决的典型题。

  1. 首先,在矩阵中任选一个格子作为路径的起点。如果路径上的第i个字符不是ch,那么这个格子不可能处在路径上的第i个位置。如果路径上的第i个字符正好是ch,那么往相邻的格子寻找路径上的第i+1个字符。除在矩阵边界上的格子之外,其他格子都有4个相邻的格子。重复这个过程直到路径上的所有字符都在矩阵中找到相应的位置。
  2. 由于回朔法的递归特性,路径可以被开成一个栈。当在矩阵中定位了路径中前n个字符的位置之后,在与第n个字符对应的格子的周围都没有找到第n+1个字符,这个时候只要在路径上回到第n-1个字符,重新定位第n个字符。
  3. 由于路径不能重复进入矩阵的格子,还需要定义和字符矩阵大小一样的布尔值矩阵,用来标识路径是否已经进入每个格子。 当矩阵中坐标为(row,col)的格子和路径字符串中相应的字符一样时,从4个相邻的格子(row,col-1),(row-1,col),(row,col+1)以及(row+1,col)中去定位路径字符串中下一个字符
  4. 如果4个相邻的格子都没有匹配字符串中下一个的字符,表明当前路径字符串中字符在矩阵中的定位不正确,我们需要回到前一个,然后重新定位。
  5. 一直重复这个过程,直到路径字符串上所有字符都在矩阵中找到合适的位置
package jianZhiOffer;
/*
 * 面试题12:矩阵中的路径
 * 题目:请设计一个桉树,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。
 * 路径可以从矩阵的任意一格开始,每一步可以在矩阵中向左,右,上,下移动一格。如果一条路径经过了矩阵的某一格,
 * 那么该路径不能再进入该格子。
 */
public class Demo012 {
	public boolean hasPath(char[] matrix,int rows,int cols,char[] str) {
		if(matrix==null || rows<1 || cols<1 || str==null) {
			return false;
		}
		//标记访问过的矩阵坐标位置,初始化为false
		boolean[] visit = new boolean[rows*cols];
		int pathLength = 0;
		for(int i=0;i<rows;i++) {
			for(int j=0;j<cols;j++) {
				if(hasPathCore(matrix,rows,cols,i,j,str,pathLength,visit)) {
					return true;
				}
			}
		}
		return false;
	}
	private boolean hasPathCore(char[] matrix,int rows,int cols,int i,
			int j,char[] str,int pathLength,boolean[] visit) {
		int index = i*cols+j;
		if(i>=rows || j>=cols || i<0 || j<0 ||
				visit[index] || matrix[index]!=str[pathLength]) {
			return false;
		}
		visit[index] = true;//当前k下标的字符匹配成功
		if(pathLength == str.length-1) 
			return true;
		pathLength++; //准备匹配下一个字符
		if(hasPathCore(matrix,rows,cols,i-1,j,str,pathLength,visit)||
		   hasPathCore(matrix,rows,cols,i+1,j,str,pathLength,visit)||
		   hasPathCore(matrix,rows,cols,i,j-1,str,pathLength,visit)||
		   hasPathCore(matrix,rows,cols,i,j+1,str,pathLength,visit))
			return true;
		pathLength--;//如果四个方向的都不对,表明上一个字符匹配不对,回退
		visit[index] = false;
		return false;
	}
	
	public static void main(String[] args) {
		char[] matrix = new char[] {'a','b','t','g',
				                    'c','f','c','s',
				                    'j','d','e','h'};
		String str = "bfce";
		Demo012 demo = new Demo012();
		System.out.println(demo.hasPath(matrix,3,4,str.toCharArray()));
		}

}

猜你喜欢

转载自blog.csdn.net/weixin_38361153/article/details/88127361