剑指offer面试题12:矩阵中的路径Java实现版

本文介绍了一种用于判断矩阵中是否存在指定字符串路径的算法。通过回溯法实现,详细解释了如何遍历矩阵并检查路径的有效性,确保路径不重复经过同一格子。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

剑指Offer 面试题12:矩阵中的路径

代码思路完全来自剑指Offer书中,因Java和c++的语言区别,有少量改动。代码整体思路都在代码注释中,仅供参考,共勉。

原题描述:

面试题12:矩阵中的路径

设计一个函数,判断在一个矩阵中是否存在包含某字符串的所有字符的路径。路径可以从任意一格开始,每步可以向上下左右移动一格。路径不能重复进入某一格子。

面试题所在章节为 2.4.3回溯法 :从解决问题每一步的所有可能选项中系统地选择一个可行方案。重复选择,直至最终状态;或者某一步不满足条件,回溯到上一步;整个过程可以形象地用树状结构表示。

package chap2;
import java.util.Arrays;
/**
 * 面试题12:矩阵中的路径
 * @author hhz
 */
public class Problem12 {
	/**
	 * 
	 * @param matrix 字符矩阵
	 * @param rows 行数
	 * @param cols 列数
	 * @param str 字符数组
	 * @return
	 */
	public static boolean hasPath(char[][] matrix,int rows,int cols,char[] str){
		//判断输入是否合法
		if(matrix==null||rows<1||cols<1||str==null)
			return false;
		//标识矩阵中的某个格子是否已经包含在已有的路径中(路径不能重复进入一个格子)
		boolean[] visited=new boolean[rows*cols];
		
		int pathLength=0;
		//不知道字符串开始字符在矩阵中的位置,需要遍历整个矩阵找到第一个字符串才能开始搜索路径
		//找到第一个字符串位置后,后续工作都是hasPathCore做的了
		for(int row=0;row<rows;row++){
			for(int col=0;col<cols;col++){
				if(hasPathCore(matrix,rows,cols,row,col,str,pathLength,visited)){
					return true;
				}
			}
		}
		return false;
	}
	private static boolean hasPathCore(char[][] matrix, int rows, int cols, int row, int col, char[] str,
			int pathLength, boolean[] visited) {
		//pathLength都自增到末尾了,说明全部字符已找到
		if(pathLength==str.length)
			return true;
		boolean hasPath=false;
		if(row>=0&&row<rows&&col>=0&&col<cols&&matrix[row][col]==str[pathLength]&&!visited[row*cols+col]){
			pathLength++;
			visited[row*cols+col]=true;
			boolean hasPathUp=false;
			boolean hasPathDown=false;
			boolean hasPathR=false;
			boolean hasPathL=false;
			//递归判断四个方向的情况
			
			hasPathUp=hasPathCore(matrix,rows,cols,row,col-1,str,pathLength,visited);
			hasPathDown=hasPathCore(matrix,rows,cols,row-1,col,str,pathLength,visited);
			hasPathR=hasPathCore(matrix,rows,cols,row,col+1,str,pathLength,visited);
			hasPathL=hasPathCore(matrix,rows,cols,row+1,col,str,pathLength,visited);
		
			//四个方向只要有一个方向找到即可
			hasPath=hasPathUp||hasPathDown||hasPathR||hasPathL;
			
			//都找不到,那就是死胡同了,回溯到上一个位置
			if(!hasPath){
				pathLength--;
				visited[row*cols+col]=false;
			}
		}
		return hasPath;
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		char[][] matrix={{'a','b','t','g'},{'c','f','c','s'},{'j','d','e','h'}};
		char[] str={'b','f','c','e'};
		boolean flag=hasPath(matrix, 3, 4, str);
		System.out.println(flag);
		String s=Arrays.deepToString(matrix);
		System.out.println(s);
		System.out.println(str);
	}

}

改了一个错误,之前在递归求每个方向之前还加了判断下标是否越界的条件,做完面试题13后发现不需要这个判断。因为每次递归开始,实际上已经有了一个判断,不符合条件的直接返回结果了。之前的判断是多余的,碰到的数组越界错误应该是在row<rows这地方写错了,多加了一个等号。

测验代码输出如下:

true
[[a, b, t, g], [c, f, c, s], [j, d, e, h]]
bfce

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值