剑指offer:JZ12 矩阵中的路径
JZ12 矩阵中的路径
描述
请设计一个函数,用来判断在一个n乘m的矩阵中是否存在一条包含某长度为len的字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。例如
矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
示例1
输入:[[a,b,c,e],[s,f,c,s],[a,d,e,e]],"abcced"返回值:true
分析
先说一下这道题使用的方法是深度优先算法dfs和回溯
dfs
深度优先算法就是一种图的遍历算法,简单来说就是从某个顶点的分支开始,尽可能深沿图的深度访问没有访问过的节点直至此分支全都访问完毕
解题
本人代码使用非递归实现了dfs+回溯,其中,一开始需要寻找矩阵中所有符合初始节点的字符位置,通过两个while循环完成算法
代码
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param matrix char字符型二维数组
* @param word string字符串
* @return bool布尔型
*/
public boolean hasPath (char[][] matrix, String word) {
/**
* 访问节点对象
*/
class HasPathNode{
char letter;
int x;
int y;
//标志其节点周围是否访问过
boolean visitUp = false;
boolean visitDown = false;
boolean visitLeft = false;
boolean visitRight = false;
HasPathNode(char letter,int x,int y) {
this.letter = letter;
this.x = x;
this.y = y;
//给出边界节点的判定
if (x == 0){
this.visitUp = true;
}
//给出边界节点的判定
if (y == 0) {
this.visitLeft = true;
}
//给出边界节点的判定
if (x == matrix.length -1) {
this.visitDown = true;
}
//给出边界节点的判定
if (y == matrix[0].length -1) {
this.visitRight = true;
}
}
}
// write code here
char words[] = word.toCharArray();
//把需要判断的字符放入链表
LinkedList<Character> wordsQueue = new LinkedList<>();
for (char item : words) {
wordsQueue.offer(item);
}
//已经经过判断的字符
Stack<Character> usedWords = new Stack<>();
//符合条件的初始节点
Queue<HasPathNode> firstLetterQueue = new LinkedList<>();
//寻找符合条件的初始节点
for (int i = 0;i<matrix.length;i++) {
for (int j = 0;j<matrix[0].length;j++) {
if (matrix[i][j] == wordsQueue.peek()) {
HasPathNode node = new HasPathNode(matrix[i][j],i,j);
firstLetterQueue.offer(node);
}
}
}
//如果没有符合的则返回false
if (firstLetterQueue.size() == 0)
return false;
//初始节点放入已使用
usedWords.push(wordsQueue.poll());
while (firstLetterQueue.size() >0) {
Stack<HasPathNode> nodeStack = new Stack<>();
nodeStack.push(firstLetterQueue.poll());
while (nodeStack.size() >0) {
if (nodeStack.peek().visitUp == false && matrix[nodeStack.peek().x - 1][nodeStack.peek().y] == wordsQueue.peek()) {
//上
HasPathNode node = new HasPathNode(wordsQueue.peek(),nodeStack.peek().x - 1,nodeStack.peek().y);
nodeStack.peek().visitUp = true;
nodeStack.push(node);
nodeStack.peek().visitDown = true;
usedWords.push(wordsQueue.poll());
}else if (nodeStack.peek().visitDown == false && matrix[nodeStack.peek().x + 1][nodeStack.peek().y] == wordsQueue.peek()) {
//下
HasPathNode node = new HasPathNode(wordsQueue.peek(),nodeStack.peek().x + 1,nodeStack.peek().y);
nodeStack.peek().visitDown = true;
nodeStack.push(node);
nodeStack.peek().visitUp = true;
usedWords.push(wordsQueue.poll());
}else if (nodeStack.peek().visitLeft == false && matrix[nodeStack.peek().x][nodeStack.peek().y - 1] == wordsQueue.peek()) {
//左
HasPathNode node = new HasPathNode(wordsQueue.peek(),nodeStack.peek().x,nodeStack.peek().y - 1);
nodeStack.peek().visitLeft = true;
nodeStack.push(node);
nodeStack.peek().visitRight = true;
usedWords.push(wordsQueue.poll());
}else if (nodeStack.peek().visitRight == false && matrix[nodeStack.peek().x][nodeStack.peek().y + 1] == wordsQueue.peek()) {
//右
HasPathNode node = new HasPathNode(wordsQueue.peek(),nodeStack.peek().x,nodeStack.peek().y + 1);
nodeStack.peek().visitRight = true;
nodeStack.push(node);
nodeStack.peek().visitLeft = true;
usedWords.push(wordsQueue.poll());
}else {
nodeStack.pop();
if (usedWords.size() != 1) {
wordsQueue.addFirst(usedWords.pop());
}
}
if (wordsQueue.size() == 0)
return true;
}
}
return false;
}
剑指offer:JZ12 矩阵中的路径的更多相关文章
- 剑指 Offer 12. 矩阵中的路径 + 递归 + 深搜 + 字符串问题
剑指 Offer 12. 矩阵中的路径 题目链接 题目类似于迷宫的搜索. 需要注意的是,需要首先判断起始搜索的位置,可能有多个起点,都需要一一尝试. 每轮迭代的时候记得将是否遍历标记数组还原为未遍历的 ...
- 力扣 - 剑指 Offer 12. 矩阵中的路径
题目 剑指 Offer 12. 矩阵中的路径 思路1(回溯.DFS) 这题可以使用回溯+递归来解决,思路如下: 将二维数组的每一个元素都作为起点进行回溯查找 每次查找的时候,都有四个方向,但是上一个方 ...
- 【Java】 剑指offer(11) 矩阵中的路径
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字 ...
- Go语言实现:【剑指offer】矩阵中的路径
该题目来源于牛客网<剑指offer>专题. 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向 ...
- 剑指Offer 65. 矩阵中的路径 (回溯)
题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.如果一条路径经过了矩阵中 ...
- [剑指Offer] 65.矩阵中的路径
题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.如果一条路径经过了矩阵中 ...
- 剑指offer:矩阵中的路径(递归回溯法DFS类似迷宫)
1. 题目描述 /* 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径. 路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子. 如果一条 ...
- 剑指offer——13矩阵中的路径
题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.如果一条路径经过了矩阵中 ...
- 剑指 Offer 12. 矩阵中的路径
题目描述 是一道很常见的深搜题目,不过里面要考虑一些边界问题,比如走过的路径是不能再次走入的,所以我这里我自己的 代码想到是利用一个新的二维的数组,记录走过的路径,不过题解的直接将原二维数组中的路径隐 ...
- [剑指Offer]12-矩阵中的路径(回溯)
题目链接 https://www.nowcoder.com/practice/c61c6999eecb4b8f88a98f66b273a3cc?tpId=13&tqId=11218&t ...
随机推荐
- Stream流用于按照对象中某一属性来对集合去重+简单数据类型集合的去重
上次对Stream流来进行分组的文章很多人看,想看的可以来这: Stream流来进行集合分组 这次小编又带来Stream的去重,话不多数,直接上代码: 这是对简单数据类型的去重 //字符串集合进行简单 ...
- java 线程基础篇,看这一篇就够了。
前言: Java三大基础框架:集合,线程,io基本是开发必用,面试必问的核心内容,今天我们讲讲线程. 想要把线程理解透彻,这需要具备很多方面的知识和经验,本篇主要是关于线程基础包括线程状态和常用方法. ...
- 性能测试工具JMeter 基础(一)—— 安装、配置环境变量
JMeter下载 下载地址:https://jmeter.apache.org/download_jmeter.cgi 下载完成后解压后可直接使用,不用进行安装 环境变量配置 新增变量名:JMETER ...
- Redis++:Redis 内存爆满 之 淘汰策略
前言: 我们的redis使用的是内存空间来存储数据的,但是内存空间毕竟有限,随着我们存储数据的不断增长,当超过了我们的内存大小时,即在redis中设置的缓存大小(maxmeory 4GB),redis ...
- VMware安装IPFire防火墙镜像
之后便可以通过WEB登录到管理页面(admin账号,密码是在上面配置的) 详细可参考:https://www.mobibrw.com/2016/4900
- openswan协商流程之(六):main_inI3_outR3()
主模式第六包:main_inI3_outR3 1. 序言 main_inI3_outR3()函数是ISAKMP协商过程中第六包的核心处理函数的入口,第五六包主要用来验证对方的身份信息,同时此报文也是加 ...
- Linux残留的EFI启动项删除后又恢复的问题
电脑Windows + Fedora双系统,UEFI启动,共用同一个EFI分区.现在删除了Fedora系统,那么应该将EFI分区中的Fedora启动项也删除之. 按照网上的办法,在Windows上,尝 ...
- python库--tensorflow--io操作
方法 返回值类型 参数 说明 .train.Saver() 实例s var_list=None 指定被保存和恢复的变量 dict: {name: 变量} list: [变量] None: 所有save ...
- 源码解析Grpc拦截器(C#版本)
前言 其实Grpc拦截器是我以前研究过,但是我看网上相关C#版本的源码解析相对少一点,所以笔者借这篇文章给大家分享下Grpc拦截器的实现,废话不多说,直接开讲(Grpc的源码看着很方便,包自动都能还原 ...
- 一文彻底搞懂Hive的数据存储与压缩
目录 行存储与列存储 行存储的特点 列存储的特点 常见的数据格式 TextFile SequenceFile RCfile ORCfile 格式 数据访问 Parquet 测试 准备测试数据 存储空间 ...