本文参考自《剑指offer》一书,代码采用Java语言。

更多:《剑指Offer》Java实现合集  

题目

  请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用下划线标出)。但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
 A B T G
 C F C S
 J D E H

思路

  首先对所整个矩阵遍历,找到第一个字符,然后向上下左右查找下一个字符,由于每个字符都是相同的判断方法(先判断当前字符是否相等,再向四周查找),因此采用递归函数。由于字符查找过后不能重复进入,所以还要定义一个与字符矩阵大小相同的布尔值矩阵,进入过的格子标记为true。如果不满足的情况下,需要进行回溯,此时,要将当前位置的布尔值标记回false。(所谓的回溯无非就是对使用过的字符进行标记和处理后的去标记)

测试用例

  1.功能测试(多行多列矩阵中存在或者不存在路径)

  2.边界值测试(矩阵只有一行;矩阵与路径的所有字符都相同)

  3.特殊输入测试(null)

完整Java代码

(含测试代码)

/**
*
* @Description 面试题12:矩阵中的路径
*
* @author yongh
* @date 2018年9月16日 上午11:13:48
*/ // 题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有
// 字符的路径。路径可以从矩阵中任意一格开始,每一步可以在矩阵中向左、右、
// 上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入
// 该格子。例如在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字
// 母用下划线标出)。但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个
// 字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
// A B T G
// C F C S
// J D E H public class StringPathInMatrix {
public boolean hasPath(char[] matrix, int rows, int cols, char[] str) {
if (matrix == null || rows < 1 || cols < 1 || str == null) {
return false;
}
boolean[] isVisited = new boolean[rows * cols];
for (boolean v : isVisited) {
v = false;
}
int pathLength = 0;
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
if (hasPathCore(matrix, rows, cols, row, col, str, pathLength, isVisited))
return true;
}
}
return false;
} private boolean hasPathCore(char[] matrix, int rows, int cols, int row, int col, char[] str, int pathLength,
boolean[] isVisited) {
if (row < 0 || col < 0 || row >= rows || col >= cols || isVisited[row * cols + col] == true
|| str[pathLength] != matrix[row * cols + col])
return false;
if (pathLength == str.length - 1)
return true;
boolean hasPath = false;
isVisited[row * cols + col] = true;
hasPath = hasPathCore(matrix, rows, cols, row - 1, col, str, pathLength + 1, isVisited)
|| hasPathCore(matrix, rows, cols, row + 1, col, str, pathLength + 1, isVisited)
|| hasPathCore(matrix, rows, cols, row, col - 1, str, pathLength + 1, isVisited)
|| hasPathCore(matrix, rows, cols, row, col + 1, str, pathLength + 1, isVisited); if (!hasPath) {
isVisited[row * cols + col] = false;
}
return hasPath;
} // =======测试代码======== // A B T G
// C F C S
// J D E H // BFCTB
public void test1() {
char[] matrix = "ABTGCFCSJDEH".toCharArray();
int rows = 3;
int cols = 4;
char[] str = "BFCTB".toCharArray();
if (!hasPath(matrix, rows, cols, str))
System.out.println("Test1 passed.");
else
System.out.println("Test1 failed.");
} // A B T G
// C F C S
// J D E H // BFCE
public void test2() {
char[] matrix = "ABTGCFCSJDEH".toCharArray();
int rows = 3;
int cols = 4;
char[] str = "BFCE".toCharArray();
if (hasPath(matrix, rows, cols, str))
System.out.println("Test2 passed.");
else
System.out.println("Test2 failed.");
} // matrix=null
public void test3() {
char[] matrix = null;
int rows = 0;
int cols = 0;
char[] str = "BFCE".toCharArray();
if (!hasPath(matrix, rows, cols, str))
System.out.println("Test3 passed.");
else
System.out.println("Test3 failed.");
} // str=null
public void test4() {
char[] matrix = "ABTGCFCSJDEH".toCharArray();
int rows = 3;
int cols = 4;
char[] str = null;
if (!hasPath(matrix, rows, cols, str))
System.out.println("Test4 passed.");
else
System.out.println("Test4 failed.");
} // A // A
public void test5() {
char[] matrix = "A".toCharArray();
int rows = 1;
int cols = 1;
char[] str = "A".toCharArray();
if (hasPath(matrix, rows, cols, str))
System.out.println("Test5 passed.");
else
System.out.println("Test5 failed.");
} // A // B
public void test6() {
char[] matrix = "A".toCharArray();
int rows = 1;
int cols = 1;
char[] str = "B".toCharArray();
if (!hasPath(matrix, rows, cols, str))
System.out.println("Test6 passed.");
else
System.out.println("Test6 failed.");
} // AAAA
// AAAA
// AAAA // AAAAAAAAAAAA
public void test7() {
char[] matrix = "AAAAAAAAAAAA".toCharArray();
int rows = 3;
int cols = 4;
char[] str = "AAAAAAAAAAAA".toCharArray();
if (hasPath(matrix, rows, cols, str))
System.out.println("Test7 passed.");
else
System.out.println("Test7 failed.");
} public static void main(String[] args) {
StringPathInMatrix demo = new StringPathInMatrix();
demo.test1();
demo.test2();
demo.test3();
demo.test4();
demo.test5();
demo.test6();
demo.test7();
}
}
Test1 passed.
Test2 passed.
Test3 passed.
Test4 passed.
Test5 passed.
Test6 passed.
Test7 passed.

StringPathInMatrix

收获

  1.回溯法用于多个步骤,每个步骤有多个选项的问题:若当前步骤满足条件,给定一个标记,当发现之后的步骤不满足条件时,去除标记。

  2.字符串转为字符数组,使用toCharArray()方法

  3.二维数组下标的计算:row*cols+col,小心别搞错。

更多:《剑指Offer》Java实现合集  

【Java】 剑指offer(11) 矩阵中的路径的更多相关文章

  1. 剑指 Offer 12. 矩阵中的路径 + 递归 + 深搜 + 字符串问题

    剑指 Offer 12. 矩阵中的路径 题目链接 题目类似于迷宫的搜索. 需要注意的是,需要首先判断起始搜索的位置,可能有多个起点,都需要一一尝试. 每轮迭代的时候记得将是否遍历标记数组还原为未遍历的 ...

  2. 力扣 - 剑指 Offer 12. 矩阵中的路径

    题目 剑指 Offer 12. 矩阵中的路径 思路1(回溯.DFS) 这题可以使用回溯+递归来解决,思路如下: 将二维数组的每一个元素都作为起点进行回溯查找 每次查找的时候,都有四个方向,但是上一个方 ...

  3. Go语言实现:【剑指offer】矩阵中的路径

    该题目来源于牛客网<剑指offer>专题. 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向 ...

  4. 剑指offer:矩阵中的路径(递归回溯法DFS类似迷宫)

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

  5. 剑指Offer 65. 矩阵中的路径 (回溯)

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

  6. [剑指Offer] 65.矩阵中的路径

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

  7. 剑指offer——13矩阵中的路径

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

  8. 剑指 Offer 12. 矩阵中的路径

    题目描述 是一道很常见的深搜题目,不过里面要考虑一些边界问题,比如走过的路径是不能再次走入的,所以我这里我自己的 代码想到是利用一个新的二维的数组,记录走过的路径,不过题解的直接将原二维数组中的路径隐 ...

  9. [剑指Offer]12-矩阵中的路径(回溯)

    题目链接 https://www.nowcoder.com/practice/c61c6999eecb4b8f88a98f66b273a3cc?tpId=13&tqId=11218&t ...

随机推荐

  1. SDOI2017 Round2 详细题解

    这套题实在是太神仙了..做了我好久...好多题都是去搜题解才会的 TAT. 剩的那道题先咕着,如果省选没有退役就来填吧. 「SDOI2017」龙与地下城 题意 丢 \(Y\) 次骰子,骰子有 \(X\ ...

  2. LOJ #2135. 「ZJOI2015」幻想乡战略游戏(点分树)

    题意 给你一颗 \(n\) 个点的树,每个点的度数不超过 \(20\) ,有 \(q\) 次修改点权的操作. 需要动态维护带权重心,也就是找到一个点 \(v\) 使得 \(\displaystyle ...

  3. 【JVM】关于类加载器准备阶段的一道面试题目

    一个经典的延伸问题 我们来看一个经典的延伸问题,准备阶段谈到静态变量,那么对于常量和不同静态变量有什么区别? 需要明确的是,没有人能够精确的理解和记忆所有信息,如果碰到这种问题,有直接答案当然最好:没 ...

  4. emwin 之 GUI_MessageBox 阻塞特性

    2019-03-01 [小记] GUI_MessageBox 函数执行后必须手动点击关闭窗口,未关闭窗口前线程将阻塞在此处等待关闭窗口事件 [使用场景] 由于该函数不会产生任何消息, 所以可利用阻塞特 ...

  5. Python学习day9 函数Ⅰ(基础)

    函数Ⅰ(基础) 三目运算 基本结构 v =  前面  if 条件 else 后面    #条件为真v=前面,条件为假v=后面.​#等同于if 条件: v = '前面'else:    v = '后面' ...

  6. Spring MVC -- Spring框架入门(IoC和DI)

    Spring MVC是Spring框架中用于Web应用开发的一个模块.Spring MVC的MVC是Model-View-Controller的缩写.它是一个广泛应用于图像化用户交互开发中的设计模式, ...

  7. mysql 重启,修改编码utf8mb4,并修改数据库链接,生效

    1.启动:/etc/init.d/mysql start 2.停止:/etc/init.d/mysql stop 3.重启:/etc/init.d/mysql restart SHOW VARIABL ...

  8. (二分查找 结构体) leetcode33. Search in Rotated Sorted Array

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...

  9. ECShop安装及错误修复

    ecshop 商城的安装及出现错误的解决 听语音 | 浏览:600 | 更新:2016-03-04 16:02 | 标签:错误 安装 电子商务 1 2 3 4 5 6 7 分步阅读 昨天第一次安装ec ...

  10. Mac新手必看教程—让你离熟练操作mac只差十分钟

    本文收录于:风云社区(提供各类mac软件资源下载) 本文源自:什么值得买 无论轻薄办公本.还是赶超台式性能的游戏本,关注#笔记本攻略#栏目,解决笔记本电脑从选购到使用的各种问题. 引子 大部分用户接触 ...