【剑指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】
【剑指Offer学习】【面试题66:矩阵中的路径】的更多相关文章
- 【剑指Offer】面试题12. 矩阵中的路径
题目 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左.右.上.下移动一格.如果一条路径经过了矩阵的某一格,那么该路径 ...
- 《剑指offer》面试题12. 矩阵中的路径
问题描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左.右.上.下移动一格.如果一条路径经过了矩阵的某一格,那么该 ...
- 剑指Offer(书):矩阵中的路径
题目: * 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.* 路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.* 如果一条路径经 ...
- 剑指offer笔记面试题12----矩阵中的路径
题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左.右.上.下移动一格.如果一条路径经过了矩阵的某一格,那么该路径 ...
- 【剑指offer】面试题 15. 二进制中 1 的个数
面试题 15. 二进制中 1 的个数 题目描述 题目:输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. Java 实现 方法一 public class Solution { // y ...
- 【剑指offer】面试题 22. 链表中倒数第 K 个节点
面试题 22. 链表中倒数第 K 个节点
- 《剑指offer》面试题66. 构建乘积数组
问题描述 给定一个数组 A[0,1,-,n-1],请构建一个数组 B[0,1,-,n-1],其中 B 中的元素 B[i]=A[0]×A[1]×-×A[i-1]×A[i+1]×-×A[n-1].不能使用 ...
- 《剑指offer》面试题45 圆圈中最后剩下的数字(Java版本)
引言 这道题网上的讲解都是直接抄书,没意思,所以想自己写一写,补充一下,便于自己理解.另外,大家都忽略了经典解法,虽然这种解法效率不及第二种,但是我觉得在项目当中阅读性其实很重要,牺牲一点点效率保证代 ...
- 剑指offer笔记面试题3----数组中重复的数字
题目一:找出数组中重复的数字.在一个长度为n的数组里的所有数字都在0~n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数字.例如 ...
- 《剑指offer》面试题15 链表中的倒数第k个节点 Java版
书中方法:用两个节点一次遍历求得倒数第k个节点.注意头节点为空,k<=0,k大于节点个数的情况. public ListNode find(ListNode head, int k){ if(h ...
随机推荐
- idea 编辑yml文件没有联想功能,解决方案
idea 编辑yml文件没有联想功能,解决方案 https://segmentfault.com/q/1010000010556550 按Ctrl+Shift+Alt+S,点Facets如果没有添加s ...
- 九度OJ 1112:拦截导弹 (DP、最长下降子序列)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3124 解决:1525 题目描述: 某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能 ...
- 远程访问Linux的常见方式
访问方式 不加密文字界面:telnet.rsh 加密文字界面:SSH 图形界面:Xdmcp.RDP.VNC SSH SSH用来取代finger.R shell(rlogin.rcp.rsh).teln ...
- Jquery跨域调用
今天在项目中须要做远程数据载入并渲染页面,直到开发阶段才意识到ajax跨域请求的问题,隐约记得Jquery有提过一个ajax跨域请求的解决方式,于是即刻翻出Jquery的API出来研究,发现JQuer ...
- myeclipse10集成Tomcat6时出现错误
myeclipse配置Tomcat时出现错误:如图 tomcat6目录:如图 在搜集各种资料后,最终得出结论: 在Tomcat目录中新建temp文件夹,问题解决. 亲测好使.
- 对于atomic nonatomic assign retain copy strong weak的简单理解
atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作 1)atomic 设置成员变量的@property属性时,atomic是默认值,提供多线程安全 在多线程环 ...
- spring boot 使用redis 及redis工具类
1-添加maven依赖 2-添加redis配置 3-工具类 1-添加maven依赖 实际上是封装了jedis <!-- redis 依赖--> <dependency> < ...
- java之EJB
EjB,只是一个服务端运行组件,公开接口供客户端以C/S方式调用而已. 最直白,最本质的解释,可参见: http://blog.csdn.net/jojo52013145/article/detail ...
- Codeforces Round #371 (Div. 2) C. Sonya and Queries —— 二进制压缩
题目链接:http://codeforces.com/contest/714/problem/C C. Sonya and Queries time limit per test 1 second m ...
- HTML: 简单的悬停效果
1. [图片] 捕获.jpg 2. [代码][CSS]代码 body { background: #000; overflow-y: scroll; } .items { ...