剑指Offer——回溯算法解迷宫问题(java版)
剑指Offer——回溯算法解迷宫问题(java版)
以一个M×N的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计程序,对任意设定的迷宫,求出从入口到出口的所有通路。
下面我们来详细讲一下迷宫问题的回溯算法。
(入口) 0 0 1 0 0 0 1 0
0 0 1 0 0 0 1 0
0 0 1 0 1 1 0 1
0 1 1 1 0 0 1 0
0 0 0 1 0 0 0 0
0 1 0 0 0 1 0 1
0 1 1 1 1 0 0 1
1 1 0 0 0 1 0 1
1 1 0 0 0 0 0 0(出口)
该图是一个迷宫的图。1代表是墙不能走,0是可以走的路线。只能往上下左右走,直到从左上角到右下角出口。
做法是用一个二维数组来定义迷宫的初始状态,然后从左上角开始,不停的去试探所有可行的路线,碰到1就结束本次路径,然后探索其他的方向,当然我们要标记一下已经走的路线,不能反复的在两个可行的格子之间来回走。直到走到出口为止,算找到了一个正确路径。
程序如下,具体做法看注释即可。
package cn.edu.ujn.demo;
/**
* @author SHQ
*
* 迷宫问题求解
*
* 思路
* 递归+回溯
*
* 按照右-->左-->下-->上的顺序寻路,已走过的路径用5标志
*
*
*/
public class MiGong {
public static void main(String[] args) {
int maxRow,maxLine,p;
Scanner in = new Scanner(System.in);
Pattern pattern = Pattern.compile("[ ]+");
String s = in.nextLine();
String [] str = pattern.split(s);
// 获取行
maxRow = Integer.parseInt(str[0]);
// 获取列
maxLine = Integer.parseInt(str[1]);
// 获取能量值
// p = Integer.parseInt(str[2]);
int [][] array = new int [maxRow][maxLine];
for(int i = 0; i < maxRow; i++){
for(int j = 0; j < maxLine; j++){
array[i][j] = in.nextInt();
}
}
Long start = System.currentTimeMillis();
new MiGong().check(0, 0, array, maxRow, maxLine);
Long end = System.currentTimeMillis();
System.out.println("耗时:" + (end-start) + "ms");
}
/**
* 制定走的规则
* @param i
* @param j
* @param array
* @param maxRow
* @param maxLine
*/
private void check(int i, int j, int[][] array, int maxRow, int maxLine) {
// 递归出口(如果到达右下角出口)
if (i == maxRow - 1 && j == maxLine - 1) {
print(array, maxRow, maxLine);
return;
}
//向右走
if (canMove(i, j, i, j + 1, array, maxRow, maxLine)) {
// 已走过的点置标志位5
array[i][j] = 5;
// 从下一个点继续寻路
check(i, j + 1, array, maxRow, maxLine);
// 均不可行,则恢复现场
array[i][j] = 0;
}
//向左走
if (canMove(i, j, i, j - 1, array, maxRow, maxLine)) {
// 标记为已走
array[i][j] = 5;
// 递归调用
check(i, j - 1, array, maxRow, maxLine);
array[i][j] = 0;
}
//向下走
if (canMove(i, j, i + 1, j, array, maxRow, maxLine)) {
array[i][j] = 5;
check(i + 1, j, array, maxRow, maxLine);
array[i][j] = 0;
}
//向上走
if (canMove(i, j, i - 1, j, array, maxRow, maxLine)) {
array[i][j] = 5;
check(i - 1, j, array,maxRow, maxLine);
array[i][j] = 0;
}
}
/**
* 判断[i,j]-->[targetI,targetJ]是否可行
* @param i
* @param j
* @param targetI
* @param targetJ
* @param array
* @param maxRow
* @param maxLine
* @return boolean 可否通过
*/
private boolean canMove(int i, int j, int targetI, int targetJ, int[][] array, int maxRow, int maxLine) {
// System.out.println("从第" + (i + 1) + "行第" + (j + 1) + "列,走到第" + (targetI + 1) + "行第" + (targetJ + 1) + "列");
if (targetI < 0 || targetJ < 0 || targetI >= maxRow || targetJ >= maxLine) {
// System.out.println("到达最左边或最右边,失败了");
return false;
}
if (array[targetI][targetJ] == 1) {
// System.out.println("目标是墙,失败了");
return false;
}
//避免在两个空格间来回走
if (array[targetI][targetJ] == 5) {
// System.out.println("来回走,失败了");
return false;
}
return true;
}
/**
* 打印可行路径
* @param array
* @param maxRow
* @param maxLine
*/
private void print(int [][] array, int maxRow, int maxLine) {
System.out.println("得到一个解:");
for (int i = 0; i < maxRow; i++) {
for (int j = 0; j < maxLine; j++) {
System.out.print(array[i][j] + " ");
}
System.out.println();
}
}
}
计算结果如下:
美文美图
剑指Offer——回溯算法解迷宫问题(java版)的更多相关文章
- 剑指Offer——回溯算法
剑指Offer--回溯算法 什么是回溯法 回溯法实际是穷举算法,按问题某种变化趋势穷举下去,如某状态的变化用完还没有得到最优解,则返回上一种状态继续穷举.回溯法有"通用的解题法"之 ...
- 剑指Offer——分治算法
剑指Offer--分治算法 基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更 ...
- 剑指Offer——动态规划算法
剑指Offer--动态规划算法 什么是动态规划? 和分治法一样,动态规划(dynamic programming)是通过组合子问题而解决整个问题的解. 分治法是将问题划分成一些独立的子问题,递归地求解 ...
- 剑指Offer——贪心算法
剑指Offer--贪心算法 一.基本概念 所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解.虽然贪心算法不能对 ...
- 《剑指offer》算法题第十二天
今天是<剑指offer>算法题系列的最后一天了,但是这个系列并没有包括书上的所有题目,因为正如第一天所说,这些代码是在牛客网上写并且测试的,但是牛客网上并没有涵盖书上所有的题目. 今日题目 ...
- 《剑指offer》算法题第一天
按照个人计划,从今天开始做<剑指offer>上面的算法题,练习平台为牛客网,上面对每道题都有充分的测试实例,感觉还是很不错的.今天下午做了四道题,分别为: 1. 二叉树的深度(书55题) ...
- JS数据结构与算法 - 剑指offer二叉树算法题汇总
❗❗ 必看经验 在博主刷题期间,基本上是碰到一道二叉树就不会碰到一道就不会,有时候一个下午都在搞一道题,看别人解题思路就算能看懂,自己写就呵呵了.一气之下不刷了,改而先去把二叉树的基础算法给搞搞懂,然 ...
- 《剑指offer》算法题第十天
今日题目: 数组中的逆序对 两个链表的第一个公共节点 数字在排序数组中出现的次数 二叉搜索树的第k大节点 字符流中第一个不重复的字符 1. 数组中的逆序对 题目描述: 在数组中的两个数字,如果前面一个 ...
- 《剑指offer》算法题第十一天
今日题目: 滑动窗口的最大值 扑克牌中的顺子 圆圈中最后剩下的数字 求1+2+3+...+n 不用加减乘除做加法 构建乘积数组 今天的题目比较有意思,可以学到很多知识,包括第1题中的数据结构——双向队 ...
随机推荐
- [COGS 2524]__完全平方数
Description 一个数如果是另一个整数的完全平方,那么我们就称这个数为完全平方数(Pefect Sqaure),也称平方数.小A认为所有的平方数都是很perfect的~ 于是他给了小B一个任务 ...
- USACO 2017 US Open
只会做T1,FallDream T2 n^2暴力AC,太强啦. T1.Modern Art 题目大意:有一个n*n的矩阵,一开始都是0,你有n^2种颜色,编号1到n^2,每次可以选出一种颜色涂满一个子 ...
- ●ZOJ 2112 Dynamic Rankings
●赘述题目 对于一个长为n(n<50000)的序列(序列中的数小于1000000000),现有如下两种指令: Q a b c:询问区间[a,b]中第c小的数. C p b:将序列中的从左往右数第 ...
- 51 nod 1188 最大公约数之和 V2
1188 最大公约数之和 V2 题目来源: UVA 基准时间限制:2 秒 空间限制:262144 KB 分值: 160 难度:6级算法题 给出一个数N,输出小于等于N的所有数,两两之间的最大公约数 ...
- hihocoder——1041国庆出游(搜索)
描述 小Hi和小Ho准备国庆期间去A国旅游.A国的城际交通比较有特色:它共有n座城市(编号1-n):城市之间恰好有n-1条公路相连,形成一个树形公路网.小Hi计划从A国首都(1号城市)出发,自驾遍历所 ...
- Codeforces Round #430 D. Vitya and Strange Lesson
Today at the lesson Vitya learned a very interesting function - mex. Mex of a sequence of numbers is ...
- Java内存模型之重排序
参考链接:https://blog.csdn.net/huzhigenlaohu/article/details/51595676
- laravel实现支付宝支付功能
起因 前段时间因为项目中需要实现支付宝手机网站支付功能,所以写下这篇文章以作记录,不足之处,欢迎指教. 后端框架:Laravel 5.5 业务功能 适用于商家在移动端网页应用中集成支付宝支付功能.商家 ...
- gulp将多张小图自动合成雪碧图
最近一直在做移动端的改版项目,做之前老大就跟我说了好几次,说这次改版一定要用雪碧图减少一个页面的图片的请求次数,能加快页面的加载速度就一定要加快,我说可以.因为之前的项目开发时间过短,也没有时间去慢慢 ...
- 项目管理软件系列-Linux一键安装禅道
linux用一键安装包 简介:本文介绍如何在linux下面使用禅道一键安装包搭建禅道的运行环境. linux一键安装包内置了apache, php, mysql这些应用程序,只需要下载解压缩即可运行禅 ...