矩阵中的路径 AcWing (JAVA)

news2025/1/16 1:04:03

请设计一个函数,用来判断在一个矩阵中是否存在一条路径包含的字符按访问顺序连在一起恰好为给定字符串。

路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。

如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。

注意:

输入的路径字符串不为空; 所有出现的字符均为大写英文字母;
数据范围 矩阵中元素的总个数 [0,900] 。
路径字符串的总长度 [1,900] 。

样例:

matrix= [
[“A”,“B”,“C”,“E”],
[“S”,“F”,“C”,“S”],
[“A”,“D”,“E”,“E”]
]

str=“BCCE” , return “true”

str=“ASAE” , return “false”

解题思路: 本题思路是一个典型的迷宫问题的衍生题。核心思路依旧是 递归与回溯也就是暴力破解法。
(如果对回溯没有概念的话,可以看看这个大哥的视频,讲的是真不错,不懂可以反复观看和模拟:回溯问题)
本题的大致解题过程也很清晰:
1 . 首先从矩阵左上角开始,选一个字母作为路径 起点,判断是否和给定字符串 str 第一个字符一样,如果不一样就在矩阵中按顺序选下一个字符直到一样为止。再对选取字符进行标记: (这需要两个for循环)
2 . 利用递归继续以上一次选取字符位置为起点,进行左右上下探索,如果探索的字符与str的第二个字符一样,那么就对矩阵中此字符标记为已经来过,并以此字符为新起点继续递归探索下面的字符,并以此类推继续执行第 2 步。
(如果左右上下的探索中都没有符合条件的字符,那么就可以结束本次探索,解除对矩阵中上一个字符的标记(回溯)并执行第 1 步开始新的探索。)

解题方式可以用树来操作:
在这里插入图片描述
理论成立代码如下(正确代码):

class Solution {
    public boolean hasPath(char[][] matrix, String str) {
           for(int i = 0; i < matrix.length; i ++) {
        	   for(int j = 0; j < matrix[0].length; j ++) {//按顺序选取起点
        		   char a = matrix[i][j];//记录本字符
        		   if(dfs(matrix, i, j, 0, str)) return true;//存在一条符合的路径即可退出
        		   matrix[i][j] = a;//回溯
        	   }
        	  
           }
           return false;//没有一条符合条件的路径那么返回false
    }
    public boolean dfs(char matrix[][], int i, int j, int k, String str) {
    	if(matrix[i][j] != str.charAt(k)) return false;//不相同直接退出
    	if(k == str.length() - 1) return true;//上一个条件说明对应字符相等,此条件判断此字符是否是最后一个字符,是的话直接退出
    	matrix[i][j] = 1;//标记此字符已经访问过,继续下次的探索
    	int fx[] = {0, 0, -1, 1};
    	int fy[] = {-1, 1, 0, 0};//左右上下四个新探索方向
    	int fxx = 0, fyy = 0;
    	for(int z = 0; z < 4; z ++) {
    		fxx = i + fx[z];
    		fyy = j + fy[z];
    		if(fxx >= 0 && fxx < matrix.length && fyy >= 0 && fyy < matrix[0].length && matrix[fxx][fyy] != 1) {
    		   //需要判断新方向是否超出矩阵边界,是否已经被访问过,不符合条件则不探索
    			char a = matrix[fxx][fyy];
    		   if(dfs(matrix, fxx, fyy, k + 1, str)) return true;//路径存在直接退出返回true
    		   matrix[fxx][fyy] = a;//回溯
    		}
    	}
    	return false;//路径不存在,继续找下一个新起点。
    }
}

***************************************************************************************************************************

进阶:由于最后一个测试点数据庞大,如果在发现路径后,不直接退出,而是对路径回溯的话,那么就会超时。超时代码如下:

import java.util.*;

public class Main {
	 
    public static void main(String[] args) {
     Solution s = new Solution();
     char a[][]= {{'A', 'B', 'C', 'E'},
    		      {'S', 'F', 'C', 'S'},
    		      {'A', 'D', 'E', 'E'},
    		       };
    
     System.out.println(s.hasPath(a, "BCCE"));
     //System.out.print();
     for(int i = 0 ; i < a.length; i ++) {
    	 for(int j = 0; j < a[0].length; j ++) {
    		 System.out.print(a[i][j] + " ");
    	 }
    	 System.out.println();
     }
 	  }
 
}
class Solution {
    public boolean hasPath(char[][] matrix, String str) {
    	if(matrix.length == 0)
    		return false;
        for(int i = 0; i < matrix.length; i ++) {
        	for(int j = 0; j < matrix[0].length; j ++) {
        		char a = matrix[i][j];
        		if(dfs(matrix, i, j, 0, str))  return true;
        		matrix[i][j] = a;
        	}
        }
        return false;
    }
    public boolean dfs(char matrix [][],int i, int j, int k, String str) {
    	   boolean judge = false;
    	   if(k == str.length()) return false;
    	   if(str.charAt(k) == matrix [i][j]) {
    	   if(k == str.length() - 1 && matrix[i][j] == str.charAt(k)) return true;
    	   }
    	   else
    	   return false;
    	   matrix[i][j] = 1;
    	   int fx[] = {0, 0, -1, 1};
    	   int fy[] = {-1, 1, 0, 0};
    	   int fxx = 0; int fyy = 0;
    	   for(int x = 0; x < 4; x ++) { 
    		   fxx = i + fx[x];
    		   fyy = j + fy[x];
    		   if(fxx >= 0 && fxx < matrix.length && fyy >= 0 && fyy < matrix[0].length && matrix[fxx][fyy] != 1) {         			   
    			   char a = matrix[fxx][fyy];
    			   if(dfs(matrix , fxx, fyy, k + 1, str))  judge = true;
    			   matrix[fxx][fyy] = a;
    		   }
    	   }
    	   return judge;
    }
}

上述方法运行结果如下:
在这里插入图片描述
由于最后一个测试点,数据量庞大,而且找到正确路径后数组的状态对我们来说已经不重要了,所以找到正确路径后跟本没必要回溯。

第一个正确代码运行结果如下所示:
在这里插入图片描述
第一个代码在发现有正确路径后直接走人,很潇洒,所以运行时间会比第二个超时代码快,而且刚好不会超时。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/365378.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【c语言】预处理

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a;> c语言学习 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是…

设计模式--工厂模式

这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。在工厂模式中&#xff0c;我们在创建对象时不会对客户端暴露创建逻辑&#xff0c;并且是通过使用一个共同的接口来指向新创建的对象。   工厂模式主要使用了C的多态特性。将存在继承关系的类&a…

通过一张照片来定位拍摄地点和网站的域名 LA CTF 2023

简介 这次打ctf遇到了一个比较经典的osint类题目&#xff0c;在这里分享一下如何做此类题目 题目链接&#xff1a; https://platform.lac.tf/challs题目简介&#xff1a; 你能猜出这个猫天堂的名字吗&#xff1f;答案是此位置的网站域。例如&#xff0c;如果答案是 ucla&…

浅谈分布式锁的原理

1.业务场景引入 在进行代码实现之前&#xff0c;我们先来看一个业务场景&#xff1a; 系统A是一个电商系统&#xff0c;目前是一台机器部署&#xff0c;系统中有一个用户下订单的接口&#xff0c;但是用户下订单之前一定要去检查一下库存&#xff0c;确保库存足够了才会给用户…

SPINAND UBI 离线烧录 开发指南

SPINAND UBI 离线烧录 开发指南 1 概述 编写目的: 介绍Sunxi SPINand 烧写时的数据布局 2 名词解释 词义UBIunsorted block imagePEBphysical erase blockLEBlogical erase block PEB 和logical block 关系 1 PEB 1 logical block 1 logical block 2 physical blocks3 总…

React从入门到精通二

React从入门到精通之购物车案例1. 购物车需求说明使用到的data list2. 项目code1. 购物车需求说明 list data展示到列表中每个item的通过按钮来控制购买的数据量删除按钮可以删除当前的itemTotal Price计算当前购物车的总的价格 使用到的data list const books [{id: 1,name…

OAK相机深度流探测草莓距离

编辑&#xff1a;OAK中国 首发&#xff1a;oakchina.cn 喜欢的话&#xff0c;请多多&#x1f44d;⭐️✍ 内容可能会不定期更新&#xff0c;官网内容都是最新的&#xff0c;请查看首发地址链接。 ▌前言 Hello&#xff0c;大家好&#xff0c;这里是OAK中国&#xff0c;我是助手…

uniapp 悬浮窗(悬浮球、动态菜单、在其他应用上层显示) Ba-FloatBall

简介&#xff08;下载地址&#xff09; Ba-FloatBall 是一款在其他应用上层显示的悬浮球插件。支持展示菜单、拖动、自动贴边等&#xff1b;支持自定义样式。 支持添加展示菜单&#xff0c;可自定义&#xff08;不添加菜单&#xff0c;可只显示悬浮球&#xff09;支持自定义悬…

一口吃不成ChatGPT,复旦版MOSS服务器被挤崩后续

ChatGPT 是目前最先进的 AI&#xff0c;由于 ChatGPT 的训练过程所需算力资源大、标注成本高&#xff0c;此前国内暂未出现对大众开放的同类产品。 适逢ChatGPT概念正火&#xff0c;2 月 21 日&#xff0c;复旦团队发布首个中国版类 ChatGPT 模型「MOSS」&#xff0c;没想到瞬时…

Python-生成列表

1.生成列表使用列表前必须先生成列表。1.1使用运算符[ ]生成列表在运算符[ ]中以逗号隔开各个元素会生成包含这些元素的新列表。另外&#xff0c;如果[ ]中没有元素就会生成空列表示例>>> list01 [] >>> list01 [] >>> list02 [1, 2, 3] >>…

云、安全、网络三位一体,Akamai 推出大规模分布式边缘和云平台 Akamai Connected Cloud

出品 | CSDN 云计算 云服务市场规模在持续增长。 基于网络技术积累与优势&#xff0c;与布局边缘计算之后&#xff0c;巨头 Akamai 在继续推进它的技术与产品进程。近日&#xff0c;Akamai 正式推出大规模分布式边缘和云平台 Akamai Connected Cloud&#xff0c;包含云计算、安…

软考学习笔记(题目知识记录)

答案为 概要设计阶段 本题涉及软件工程的概念 软件工程的任务是基于需求分析的结果建立各种设计模型&#xff0c;给出问题的解决方案 软件设计可以分为两个阶段&#xff1a; 概要设计阶段和详细设计阶段 结构化设计方法中&#xff0c;概要设计阶段进行软件体系结构的设计&…

学生管理系统-课后程序(JAVA基础案例教程-黑马程序员编著-第六章-课后作业)

【案例6-2】 学生管理系统 【案例介绍】 1.任务描述 在一所学校中&#xff0c;对学生人员流动的管理是很麻烦的&#xff0c;本案例要求编写一个学生管理系统&#xff0c;实现对学生信息的添加、删除、修改和查询功能。每个功能的具体要求如下&#xff1a; 系统的首页&#…

视频技术基础知识

一、视频图像基础 像素&#xff1a;图像的基本单元&#xff0c;即一个带有颜色的小块分辨率&#xff1a;图像的大小或尺寸&#xff0c;用像素个数来表示。原始图像分辨率越高&#xff0c;图像就越清晰位深&#xff1a;存储每位像素需要的二进制位数&#xff1b;位深越大&#…

JAVA线程入门简介

线程入门简介什么是程序?什么是进程?什么是线程&#xff1f;单线程与多线程并发与并行线程的使用用java查看有多少个cpu创建线程的两种方式继承Thread类&#xff0c;重写run方法实现Runnable接口&#xff0c;重写run方法多线程机制为社么是start?源码解析什么是程序? 是为完…

防错料使用二维码解决方案 生产过程物料防错管理

生产过程中&#xff0c;物料的防错管理是非常重要的一环。它能够有效地防止物料错用或混用&#xff0c;从而降低产品质量问题的发生率&#xff0c;减少生产成本和生产周期&#xff0c;提高生产效率和产品质量。以下是生产过程物料防错管理的具体措施&#xff1a;1.明确物料标识…

SpringBoot Data Redis来操作Redis

SpringBoot Data Redis来操作Redis1、Redis启动Redis主要的作用安装的位置启动2、Java中来操作Redis3、Spring Data Redis(重点)测试连接配置Redis序列化器redisTemplate操作常见数据类型通用操作&#xff0c;针对不同的数据类型都可以操作申明&#xff1a; 未经许可&#xff0…

浅谈Springboot自动化配置原理

文章目录1.前言2.SpringBoot的入口3.SpringBootApplication背后的秘密4.Configuration5.ComponentScan扫描bean6.EnableAutoConfiguration7.自动配置生效1.前言 不论在工作中&#xff0c;亦或是求职面试&#xff0c;Spring Boot已经成为我们必知必会的技能项。除了某些老旧的政…

java面试题-JUC线程池

1.FutureTask的作用?FutureTask 是 Java 并发编程中的一个类&#xff0c;用于异步执行任务并获取其结果。它实现了 Future 和 Runnable 接口&#xff0c;因此可以作为一个可运行的任务提交给 Executor 执行&#xff0c;也可以通过 Future 接口获取任务执行的结果。FutureTask …

2023年DAMA-CDGA/CDGP数据治理认证选择哪家机构好?

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…