关于
我的项目
相关阅读
热度排行
- [转] 宫崎骏用动漫教给我们的人生哲理,每一句都能说到心里! - (日期:[八月 24, 2013] 点击:[53,521])
- Google 网页爬虫报告无法连接站点解决办法 - (日期:[七月 20, 2014] 点击:[38,659])
- 架设Tiny Tiny RSS(TTRSS)阅读器,找回Google Reader! - (日期:[九月 27, 2013] 点击:[27,792])
- SkyDrive、DropBox和Google Drive三大公有云存储服务对比 - (日期:[六月 25, 2013] 点击:[25,630])
- 升级到至强E5440后,与i5 CPU笔记本性能对比 - (日期:[二月 18, 2014] 点击:[23,793])
- 公钥私钥加密解密数字证书数字签名详解 - (日期:[四月 19, 2014] 点击:[22,973])
- 本站建站技术合集 - (日期:[九月 20, 2013] 点击:[22,535])
- 使用OpenerDNS解决无法访问Google的问题 - (日期:[七月 5, 2014] 点击:[21,839])
- WordPress博客添加“返回顶部”按钮 - (日期:[七月 14, 2013] 点击:[21,246])
- Linux文件系统基础之inode和dentry - (日期:[三月 13, 2015] 点击:[20,198])
- 云存储中的HTTP鉴权算法分析 - (日期:[二月 7, 2014] 点击:[18,650])
- 存储基础知识之——磁盘阵列原理及操作实战 - (日期:[二月 9, 2014] 点击:[17,528])
- 精选37条强大的常用linux shell命令组合 - (日期:[九月 4, 2013] 点击:[17,456])
- DNS原理、架构和配置详解 - (日期:[九月 6, 2013] 点击:[16,845])
- Netty和Jetty的Java NIO 网络框架模型分析 - (日期:[七月 13, 2013] 点击:[16,342])
- CoreOS 初识之安装 - (日期:[十一月 16, 2014] 点击:[16,207])
- Windows与Linux文件系统互访的几种方法 - (日期:[八月 21, 2014] 点击:[15,738])
- Dijkstra算法求解最短路径分析 - (日期:[七月 12, 2014] 点击:[14,937])
- NAS解决方案实现多媒体文件共享播放 - (日期:[十二月 21, 2014] 点击:[13,957])
- 简介 - (日期:[九月 1, 2012] 点击:[13,781])
- 如何编程实现 2 + 2 = 5? - (日期:[六月 2, 2014] 点击:[13,275])
- 搭建了一个iNews程序 - (日期:[十月 15, 2013] 点击:[13,249])
- 2014年9月曝出的Bash ShellShock漏洞简析 - (日期:[九月 26, 2014] 点击:[13,163])
- 彻底解决WordPress博客垃圾评论的问题 - (日期:[八月 5, 2013] 点击:[13,134])
- 如何使用1M的内存排序100万个8位数 - (日期:[三月 27, 2014] 点击:[12,568])
- 全部日志列表 - (日期:[十一月 11, 2012] 点击:[12,406])
- 关于回调函数和this指针探讨 - (日期:[八月 24, 2014] 点击:[12,239])
- 给定一个long型常量,其值为x,给定long型变量a,要求a & x 的取值集合 - (日期:[九月 8, 2012] 点击:[11,722])
- 开源好用的电子书管理服务Talebook(Calibre网络版)安装使用指南 - (日期:[四月 23, 2022] 点击:[11,716])
- WordPress建站必备实用插件 - (日期:[八月 7, 2014] 点击:[11,381])
分类目录
文章归档
- 2025年一月 (1)
- 2024年十二月 (1)
- 2024年四月 (1)
- 2024年二月 (1)
- 2023年九月 (1)
- 2023年一月 (1)
- 2022年十月 (1)
- 2022年八月 (2)
- 2022年四月 (1)
- 2022年三月 (1)
- 2021年十二月 (2)
- 2021年十月 (2)
- 2021年九月 (1)
- 2021年八月 (1)
- 2021年五月 (1)
- 2021年三月 (2)
- 2021年一月 (2)
- 2020年十二月 (5)
- 2020年十一月 (2)
- 2020年十月 (2)
- 2020年九月 (1)
- 2020年八月 (5)
- 2020年七月 (2)
- 2019年九月 (1)
- 2018年八月 (1)
- 2018年七月 (1)
- 2018年六月 (1)
- 2018年五月 (1)
- 2018年三月 (1)
- 2018年二月 (1)
- 2018年一月 (2)
- 2017年十二月 (3)
- 2017年十月 (4)
- 2017年九月 (1)
- 2017年七月 (1)
- 2017年六月 (1)
- 2016年十二月 (1)
- 2016年十月 (1)
- 2016年九月 (1)
- 2016年七月 (2)
- 2016年六月 (1)
- 2016年二月 (3)
- 2015年十二月 (3)
- 2015年十一月 (2)
- 2015年十月 (1)
- 2015年八月 (2)
- 2015年七月 (4)
- 2015年六月 (1)
- 2015年三月 (2)
- 2015年二月 (1)
- 2015年一月 (4)
- 2014年十二月 (2)
- 2014年十一月 (2)
- 2014年十月 (5)
- 2014年九月 (8)
- 2014年八月 (11)
- 2014年七月 (17)
- 2014年六月 (7)
- 2014年五月 (15)
- 2014年四月 (16)
- 2014年三月 (14)
- 2014年二月 (5)
- 2013年十二月 (5)
- 2013年十一月 (3)
- 2013年十月 (13)
- 2013年九月 (13)
- 2013年八月 (13)
- 2013年七月 (9)
- 2013年六月 (8)
- 2013年五月 (1)
- 2013年三月 (3)
- 2013年一月 (1)
- 2012年十一月 (1)
- 2012年九月 (12)
- 2012年八月 (3)
- 2011年二月 (1)
- 2009年三月 (1)
- 2009年二月 (1)
- 2008年十一月 (1)
- 2008年六月 (1)
- 2008年四月 (1)
- 2008年三月 (1)
迷宫营救公主算法
今天下班前在公司的技术题库中看到这道题目,思路很快就有了,递归遍历每一条可能的路径,然后找出最短的路径。回家把代码写出来了。发现算法效率实在是太低了,在矩阵较小的时候还好,当矩阵稍微大一点时根本算不过来,感觉复杂度像是O((N*M)^(N*M))这个数值太庞大了,也完全没有意义。公主等到花儿都谢啦。。
貌似这位同学的算法还不错,还没来得及研究,先做个链接:http://blog.csdn.net/joseph_1118/article/details/9390301
应付较小的矩阵下面的方法还是能蒙混过关的。先发到这里,后面再继续研究优化。题目和代码都在一起:
/**
* 公主被魔王抓走了,王子需要拯救出美丽的公主。他进入了魔王的城堡,魔王的城堡是一座很大的迷宫。
* 为了使问题简单化,我们假设这个迷宫是一个N*M的二维方格。迷宫里有一些墙,王子不能通过。王子只
* 能移动到相邻(上下左右四个方向)的方格内,并且一秒只能移动一步。地图由’S’,’P’,’.’,’*’
* 四种符号构成,’.’表示王子可以通过,’*’表示墙,王子不能通过;’S’表示王子的位置;’P’表示公主
* 的位置;T表示公主存活的剩余时间,王子必须在T秒内到达公主的位置,才能救活公主。如下图所示:
*/
package com;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 公主被魔王抓走了,王子需要拯救出美丽的公主。他进入了魔王的城堡,魔王的城堡是一座很大的迷宫。
* 为了使问题简单化,我们假设这个迷宫是一个N*M的二维方格。迷宫里有一些墙,王子不能通过。王子只
* 能移动到相邻(上下左右四个方向)的方格内,并且一秒只能移动一步。地图由'S','P','.','*'
* 四种符号构成,'.'表示王子可以通过,'*'表示墙,王子不能通过;'S'表示王子的位置;'P'表示公主
* 的位置;T表示公主存活的剩余时间,王子必须在T秒内到达公主的位置,才能救活公主。如下图所示:
*/
public class SavePrincess
{
private int m;
private int n;
private char[][] visited;
private Map<Position, List<Position>> data = new HashMap<Position, List<Position>>();
private int t;
private Position s = null;
private Position p = null;
public static void main(String[] args)
{
char maze[][] = {
/* 0 1 2 3 4 5 6 7 8 9*/
/* 0 */{ '.', '*', '.', '.', '.', '*', '.', '.', '.', '.' },
/* 1 */{ '.', 'S', '*', '.', '.', '.', '.', '.', '.', '.' },
/* 2 */{ '.', '*', '*', '.', '.', '.', '.', '.', '.', '.' },
/* 3 */{ '.', '.', '*', '*', '*', '.', '.', '.', '.', '.' },
/* 4 */{ '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
/* 5 */{ '.', '.', '.', '.', '*', '.', '.', '.', '.', '.' },
/* 6 */{ '.', '.', '.', '.', '*', '.', '.', '.', '.', '.' },
/* 7 */{ '.', '.', '.', '.', '*', '.', '.', '.', '.', '.' },
/* 8 */{ '.', '.', '.', '.', '*', '.', '.', '.', '.', '.' },
/* 9 */{ '.', '.', 'P', '.', '*', '.', '.', '.', '.', '.' } };
// maze[][] = {
// /* 0 1 2 3 4 5 6 7 8 9 */
// /* 0 */{ '.', '.', '.', '*', '.', '.', '.', '.', '.', '.' },
// /* 1 */{ '.', 'S', '*', '.', '.', '.', '.', '.', '.', '.' },
// /* 2 */{ '.', '.', '*', '.', '.', '.', '.', '.', '.', '.' },
// /* 3 */{ '.', '.', '*', '*', '.', '*', '.', '.', '.', '.' },
// /* 4 */{ '.', '.', '.', '*', '.', '*', '.', '.', '.', '.' },
// /* 5 */{ '.', '.', '.', '*', '.', '.', '.', '.', '.', '.' },
// /* 6 */{ '.', '.', '*', '.', '.', '.', '.', '.', '.', '.' },
// /* 7 */{ '.', '.', '*', '.', '*', '.', '*', '.', '.', '.' },
// /* 8 */{ '.', '.', '.', '.', '*', '.', '*', '*', '*', '.' },
// /* 9 */{ '.', '.', '*', '.', '*', '.', '*', 'P', '.', '.' } };
new SavePrincess().saved(maze, 10, 8, 11);
}
/**
* @param vis
* M行N列迷宫
* @param m
* M
* @param n
* N
* @param t
* T
*
* @return boolean true表示营救成功,反之表示失败。
*/
public boolean saved(char[][] vis, int m, int n, int t)
{
this.m = m;
this.n = n;
this.visited = vis;
this.t = t;
for (int i = 0; i != m; i++)
{
for (int j = 0; j != n; j++)
{
System.out.print(visited[i][j]);
System.out.print(' ');
Position tmp = new Position(i, j);
switch (visited[i][j])
{
case '*':
break;
case 'S':
this.s = tmp;
break;
case '.':
prepareNode(i, j, tmp);
break;
case 'P':
this.p = tmp;
prepareNode(i, j, tmp);
default:
break;
}
}
System.out.println("");
}
if (s == null || p == null)
{
System.out.println("input visited error!");
return false;
}
Set<Position> excudedNode = new HashSet<Position>();
int l = findNearstWay(p, excudedNode);
if (l < 0)
{
System.out.println("failed saved the princess!");
return false;
}
else
{
System.out.println("Saved the princess in " + l + " seconds!");
return true;
}
}
private int findNearstWay(Position p2, Set<Position> excudedNode)
{
if (s.equals(p2))
{
return 0;
}
List<Position> lst = data.get(p2);
excudedNode.add(p2);
int minLen = -1;
if (lst == null)
{
return minLen;
}
for (Position o : lst)
{
if (excudedNode.contains(o))
{
continue;
}
int len = findNearstWay(o, excudedNode);
if ((len <= this.t && len != -1) && (minLen == -1 || (minLen != -1 && len < minLen)))
{
minLen = len;
}
}
excudedNode.remove(p2);
if (minLen != -1)
{
return minLen + 1;
}
else
{
return minLen;
}
}
private void prepareNode(int i, int j, Position tmp)
{
List<Position> lst1 = new LinkedList<Position>();
addOneNode(i + 1, j, lst1);
addOneNode(i, j + 1, lst1);
addOneNode(i - 1, j, lst1);
addOneNode(i, j - 1, lst1);
if (!lst1.isEmpty())
{
data.put(tmp, lst1);
}
}
private void addOneNode(int i, int j, List<Position> lst)
{
if (i >= m || i < 0 || j >= n || j < 0)
{
return;
}
switch (visited[i][j])
{
case '.':
case 'S':
lst.add(new Position(i, j));
break;
default:
break;
}
}
}
package com;
public class Position implements Comparable<Position>
{
private int i;
private int j;
public Position(int i, int j)
{
this.i = i;
this.j = j;
}
@Override
public int compareTo(Position o)
{
if (this.i == o.i && this.j == o.j)
{
return 0;
}
else if (this.i > o.i)
{
return 1;
}
else
{
if (this.i > o.j)
{
return 1;
}
else
{
return -1;
}
}
}
public boolean equals(Object o)
{
if (!(o instanceof Position))
{
return false;
}
if (this.compareTo((Position) o) == 0)
{
return true;
}
return false;
}
public int hashCode()
{
int result = 17;
result = 31 * result + i;
result = 31 * result + j;
return result;
}
public String toString()
{
return "(" + i + ", " + j + ")";
}
}
2 条评论
正解参考:链接
你给的算法是深度优先的吧?
可能是因为深度优先遍历时,步长变化太短了吧,如果把深度类比为循序查找。
好像在你算法中没有看到记录状态,如果记录下已走过的路径,是不是就会节约很多次搜索时间呢?保证一个能走的格子只会走一次。
之前看严蔚敏讲走迷宫时,他的迷宫数组有个是否走过的状态,采用深度遍历时,只要当该节点东南西北都走不通,回滚到上一步时,就会将该节点标记。
你看下我的理解对不,是否可以提升下性能。