题目:请设计一个函数,用来推断在一个矩阵中是否存在一条包括某字符串全部字符的路径。路径能够从矩阵中随意一格開始。每一步能够在矩阵中间向左、右、上、下移动一格。假设一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。


举例分析

  比如在以下的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:矩阵中的路径】的更多相关文章

  1. 【剑指Offer】面试题12. 矩阵中的路径

    题目 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左.右.上.下移动一格.如果一条路径经过了矩阵的某一格,那么该路径 ...

  2. 《剑指offer》面试题12. 矩阵中的路径

    问题描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左.右.上.下移动一格.如果一条路径经过了矩阵的某一格,那么该 ...

  3. 剑指Offer(书):矩阵中的路径

    题目: * 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.* 路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.* 如果一条路径经 ...

  4. 剑指offer笔记面试题12----矩阵中的路径

    题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左.右.上.下移动一格.如果一条路径经过了矩阵的某一格,那么该路径 ...

  5. 【剑指offer】面试题 15. 二进制中 1 的个数

    面试题 15. 二进制中 1 的个数 题目描述 题目:输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. Java 实现 方法一 public class Solution { // y ...

  6. 【剑指offer】面试题 22. 链表中倒数第 K 个节点

    面试题 22. 链表中倒数第 K 个节点

  7. 《剑指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].不能使用 ...

  8. 《剑指offer》面试题45 圆圈中最后剩下的数字(Java版本)

    引言 这道题网上的讲解都是直接抄书,没意思,所以想自己写一写,补充一下,便于自己理解.另外,大家都忽略了经典解法,虽然这种解法效率不及第二种,但是我觉得在项目当中阅读性其实很重要,牺牲一点点效率保证代 ...

  9. 剑指offer笔记面试题3----数组中重复的数字

    题目一:找出数组中重复的数字.在一个长度为n的数组里的所有数字都在0~n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重复的数字.例如 ...

  10. 《剑指offer》面试题15 链表中的倒数第k个节点 Java版

    书中方法:用两个节点一次遍历求得倒数第k个节点.注意头节点为空,k<=0,k大于节点个数的情况. public ListNode find(ListNode head, int k){ if(h ...

随机推荐

  1. css实现弹出窗体始终垂直水平居中

    <!DOCTYPE html><html> <head> <meta charset=" utf-8"> <meta name ...

  2. Caffe学习系列(12):训练和测试自己的图片--linux平台

    Caffe学习系列(12):训练和测试自己的图片   学习caffe的目的,不是简单的做几个练习,最终还是要用到自己的实际项目或科研中.因此,本文介绍一下,从自己的原始图片到lmdb数据,再到训练和测 ...

  3. Tabs in Non-RootViewController Scenarios

    新建空工程如图 添加一个MainStoryboard如图 设置启动项为MainStoryboard 重写AppDelegate的Window方法 public override UIWindow Wi ...

  4. EasyDarwin自动停止推流

    原文转自:http://blog.csdn.net/ss00_2012/article/details/51441753 我们使用EasyDarwin的推流转发来进行媒体直播的时候,有时会有这样一个需 ...

  5. jQuery 给div绑定单击事件

    说明:这篇随笔介绍的是怎么给div添加单击(click)事件.不再废话 直接看代码 <%@ Page Language="C#" AutoEventWireup=" ...

  6. ora-12170 与 Oracle lsnrctl

    在startup 启动数据库后,使用plsql去连接数据库时, 出现ora-12170 错误:   在启动.关闭或者重启oracle监听器之前确保使用lsnrctl status命令检查oracle监 ...

  7. BNUOJ 34978 汉诺塔 (概率dp)

    题目分析:对于 i 个盘 , 须要移动多少步,取决于最大的盘子在哪个杆上.在C杆上,则最大的盘不须要移动,由于初始状态一定是满足盘由下到上盘子依次变小的,仅仅须要移动i - 1个盘.假设在A杆上,则首 ...

  8. hihocoder #1062 : 最近公共祖先·一(小数据量 map+set模拟+标记检查 *【模板】思路 )

    #1062 : 最近公共祖先·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho最近发现了一个神奇的网站!虽然还不够像58同城那样神奇,但这个网站仍然让小Ho乐在 ...

  9. codeforces 467B Fedor and New Game 解题报告

    题目链接:http://codeforces.com/contest/467/problem/B 题目意思:有 m + 1 个 player 和 n 种类型的 soldiers.每个player被赋予 ...

  10. python学习笔记:第四天( 字符串)

    Python3 字符串 字符串是 Python 中最常用的数据类型.我们可以使用引号('或")来创建字符串. 在Python2中,普通字符串是以8位ASCII码进行存储的,而Unicode字 ...