- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我试过下面的代码,但它没有给我正确的答案。
这是问题陈述。
Suppose you have a 2-D grid. Each point is either land or water. There is also a start point and a goal.
There are now keys that open up doors. Each key corresponds to one door.
Implement a function that returns the shortest path from the start to the goal using land tiles, keys and open doors.
Data Representation
The map will be passed as an array of strings.
A map can have the following tiles.
0 = Water
1 = Land
2 = Start
3 = Goal
uppercase = door
lowercase = key
The grid can be like this:
{{'0', '2', '1', '1', '1'},
{'0', '1', '0', '0', '1'},
{'0', '0', '0', '0', '1'},
{'0', '0', 'A', '0', '1'},
{'1', '1', 'a', '1', '1'},
{'1', 'b', '0', '0', 'B'},
{'1', '1', '0', '0', '1'},
{'0', '1', '0', '0', '3'}};So the shortest path should be: 01->02->03->04->14->24->34->44->43->42->41->51->41->42->43->44->54->64->74
我的代码是这样的:
public class shortestPath {
static int shortest = Integer.MAX_VALUE;
static String path = "";
static ArrayList<ArrayList<int[]>> res = new ArrayList<ArrayList<int[]>>();
public static void main(String[] args) {
char[][] board = {{'0', '2', '1', '1', '1'},
{'0', '1', '0', '0', '1'},
{'0', '0', '0', '0', '1'},
{'0', '0', 'A', '0', '1'},
{'1', '1', 'a', '1', '1'},
{'1', 'b', '0', '0', 'B'},
{'1', '1', '0', '0', '1'},
{'0', '1', '0', '0', '3'}};
System.out.println(findShortest(board));
System.out.println(path);
}
public static int findShortest(char[][] board) {
if (board == null || board.length == 0 || board[0].length == 0) return 0;
int row = board.length;
int col = board[0].length;
int[] start = new int[2];
int[] end = new int[2];
int[][] visited = new int[row][col];
HashMap<Character, ArrayList<int[]>> hm = new HashMap<>();
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (board[i][j] == '2') {
start = new int[]{i, j};
}
if (board[i][j] == '3') {
end = new int[]{i, j};
}
if (Character.isUpperCase(board[i][j])) {
char key = Character.toLowerCase(board[i][j]);
if (hm.containsKey(key)) {
hm.get(key).add(new int[]{i, j});
} else {
ArrayList<int[]> al = new ArrayList<>();
al.add(new int[]{i, j});
hm.put(key, al);
}
board[i][j] = '0';
}
}
}
//HashSet<Character> hs = new HashSet<Character>();
//helper2(board, hs, start[0], start[1], row, col, 0, visited, new StringBuilder(), new ArrayList<int[]>(), res);
helper(board, hm, start[0], start[1], row, col, 0, visited, new StringBuilder());
return shortest;
}
public static void helper(char[][] board, HashMap<Character, ArrayList<int[]>> hm, int r, int c, int row, int col, int count, int[][] visited, StringBuilder sb) {
// System.out.println(r + " " + c);
visited[r][c] = visited[r][c] + 1;
sb.append(r).append(c).append("->");
if (board[r][c] == '3') {
System.out.println(count);
if (shortest > count) {
path = sb.deleteCharAt(sb.length() - 1).deleteCharAt(sb.length() - 1).toString();
sb.append("->");
shortest = count;
}
//return;
//shortest = Math.min(shortest, count);
}
if (Character.isLowerCase(board[r][c])) { // if this is the key;
if (hm.containsKey(board[r][c])) {
for (int[] i : hm.get(board[r][c])) {
board[i[0]][i[1]] = '1';
}
}
}
if (r + 1 < row && board[r + 1][c] != '0' && visited[r + 1][c] < 2) {
helper(board, hm, r + 1, c, row, col, count + 1, visited, sb);
}
if (c + 1 < col && board[r][c + 1] != '0' && visited[r][c + 1] < 2) {
helper(board, hm, r, c + 1, row, col, count + 1, visited, sb);
}
if (r - 1 >= 0 && board[r - 1][c] != '0' && visited[r - 1][c] < 2) {
helper(board, hm, r - 1, c, row, col, count + 1, visited, sb);
}
if (c - 1 >= 0 && board[r][c - 1] != '0' && visited[r][c - 1] < 2) {
helper(board, hm, r, c - 1, row, col, count + 1, visited, sb);
}
visited[r][c] = visited[r][c] - 1;
sb.delete(sb.length() - 4, sb.length());
if (Character.isLowerCase(board[r][c])) { // if this is the key;
if (hm.containsKey(board[r][c])) {
for (int[] i : hm.get(board[r][c])) {
board[i[0]][i[1]] = '0';
}
}
}
return;
}
}
最佳答案
您的问题是 visited
跟踪和锁门跟踪 (由 hm
变量管理,这是一个非常糟糕的名称)的错误实现的组合,因为名称无助于理解变量是什么/做什么)。
访问跟踪
您的小机器人经常一遍又一遍地来回走动。例如,如果您插入用于调试的打印语句:
您会得到以下结果,其中 !
表示走的路径较长,而 *
表示找到目标的路径较短:
1: ! 01->
2: ! 01->11->
3: ! 01->11->01->
4: ! 01->11->01->11->
6: ! 01->11->01->02->03->
7: ! 01->11->01->02->03->04->
8: ! 01->11->01->02->03->04->14->
9: ! 01->11->01->02->03->04->14->24->
10: ! 01->11->01->02->03->04->14->24->34->
11: ! 01->11->01->02->03->04->14->24->34->44->
12: ! 01->11->01->02->03->04->14->24->34->44->34->
13: ! 01->11->01->02->03->04->14->24->34->44->34->44->
14: ! 01->11->01->02->03->04->14->24->34->44->34->44->43->
15: ! 01->11->01->02->03->04->14->24->34->44->34->44->43->42->
16: ! 01->11->01->02->03->04->14->24->34->44->34->44->43->42->43->
17: ! 01->11->01->02->03->04->14->24->34->44->34->44->43->42->43->42->
18: ! 01->11->01->02->03->04->14->24->34->44->34->44->43->42->43->42->32->
20: ! 01->11->01->02->03->04->14->24->34->44->34->44->43->42->43->42->41->51->
21: ! 01->11->01->02->03->04->14->24->34->44->34->44->43->42->43->42->41->51->61->
22: ! 01->11->01->02->03->04->14->24->34->44->34->44->43->42->43->42->41->51->61->71->
23: ! 01->11->01->02->03->04->14->24->34->44->34->44->43->42->43->42->41->51->61->71->61->
24: ! 01->11->01->02->03->04->14->24->34->44->34->44->43->42->43->42->41->51->61->71->61->71->
26: ! 01->11->01->02->03->04->14->24->34->44->34->44->43->42->43->42->41->51->61->71->61->51->41->
27: ! 01->11->01->02->03->04->14->24->34->44->34->44->43->42->43->42->41->51->61->71->61->51->41->40->
28: ! 01->11->01->02->03->04->14->24->34->44->34->44->43->42->43->42->41->51->61->71->61->51->41->40->50->
29: ! 01->11->01->02->03->04->14->24->34->44->34->44->43->42->43->42->41->51->61->71->61->51->41->40->50->60->
30: ! 01->11->01->02->03->04->14->24->34->44->34->44->43->42->43->42->41->51->61->71->61->51->41->40->50->60->50->
31: ! 01->11->01->02->03->04->14->24->34->44->34->44->43->42->43->42->41->51->61->71->61->51->41->40->50->60->50->60->
9577: * 01->11->01->02->03->04->14->24->34->44->43->42->41->51->61->71->61->51->41->42->43->44->54->64->74->
9611: ! 01->11->01->02->03->04->14->24->34->44->43->42->41->51->61->71->61->51->50->60->50->40->41->42->43->44->54->64->74->
9612: ! 01->11->01->02->03->04->14->24->34->44->43->42->41->51->61->71->61->51->50->60->50->40->41->42->43->44->54->64->74->64->
9613: ! 01->11->01->02->03->04->14->24->34->44->43->42->41->51->61->71->61->51->50->60->50->40->41->42->43->44->54->64->74->64->74->
9623: ! 01->11->01->02->03->04->14->24->34->44->43->42->41->51->61->71->61->51->50->60->50->40->41->42->43->44->34->24->14->04->03->02->
9901: * 01->11->01->02->03->04->14->24->34->44->43->42->41->51->61->51->41->42->43->44->54->64->74->
19141: ! 01->11->01->02->03->04->14->24->34->24->34->44->43->42->41->51->61->71->61->51->50->60->50->40->41->42->43->44->54->64->74->64->74->
53941: ! 01->11->01->02->03->04->14->04->14->24->34->24->34->44->43->42->41->51->61->71->61->51->50->60->50->40->41->42->43->44->54->64->74->64->
53942: ! 01->11->01->02->03->04->14->04->14->24->34->24->34->44->43->42->41->51->61->71->61->51->50->60->50->40->41->42->43->44->54->64->74->64->74->
145776: ! 01->11->01->02->03->02->03->04->14->04->14->24->34->24->34->44->43->42->41->51->61->71->61->51->50->60->50->40->41->42->43->44->54->64->74->64->
145777: ! 01->11->01->02->03->02->03->04->14->04->14->24->34->24->34->44->43->42->41->51->61->71->61->51->50->60->50->40->41->42->43->44->54->64->74->64->74->
158937: * 01->02->03->04->14->24->34->44->43->42->41->51->61->51->41->42->43->44->54->64->74->
向前迈出的总步数:390236
那条最长的路要来回走很多路:
01->11->
01->02->03->
02->03->04->14->
04->14->24->34->
24->34->44->43->42->41->51->61->71->61->
51->50->60->
50->40->41->42->43->44->54->64->74->
64->74->
那是浪费了很多步行。
锁门跟踪
回顾一下您的逻辑:您最初将所有门更改为 0
(水)。当您遇到一把 key 时,您可以通过将棋盘值更改为 1
(土地)来解锁适合该 key 的所有门。回溯时,您将所有门更改回 0
(水)。
现在看看您的代码得出的解决方案:
01->02->03->04->14->24->34->44->43->42->41->51->61->
51->41->42->43->44->54->64->74
问题是 key 在 51
,所以当代码从那个解决方案回溯到 second 51
时,它会关上门,所以当它回到第一个 51
并尝试从那里直接走到目标时,门是关闭的,即使你有 key 。
那是因为你没有意识到你有两次 key 。
解决方案
如果您只是修复访问过的跟踪,您的代码将起作用,因为您不会两次踩到同一个键。
如果您只是修复锁定的门跟踪,即跟踪您拥有同一把 key 的多个副本,您的代码将起作用,因为您不会再次过早地锁门。
但是,对于您修改后的解决方案,请考虑以下事项:
因此,一种不同的方法是考虑它在现实生活中的运作方式。当您找到 key 时,您不会打开门,因为 1) 您不一定知道门在哪里,以及 2) 从您所站的位置无法到达门。
相反,保留一个 key 圈。当您遇到您没有的 key 时,将其添加到 key 环中。将新 key 添加到 key 圈还意味着您可以重新访问以前走过的区域。当你遇到一扇门时,如果你的 key 在 key 圈里,你就可以穿过它。
由于有 26 个可能的 key ,一个 32 位的 int
值可以作为您的 key 环。
参见 IDEONE对于仅需要 90 个步骤(而不是当前代码的 390236 个步骤)来检查所有可能/相关路径的示例实现。
关于java - 如何在带 key 和门的谜题中找到最短路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39431473/
我想实现一个 bool NAND/NOR 门。问题是我在代码本身中即时学习的门没有输入,即我事先不知道它可能有多少输入。以下是 OR 的代码。但我想不出一种方法来为 NOR/NAND 做这件事。结果的
我正试图找到用 C 语言编写 XNOR 门的最有效方法。 if(VAL1 XNOR VAL2) { BLOCK; } 有什么建议吗? 谢谢。 最佳答案 有两个操作数,这很简单: if (val
我正在尝试进行 laravel 基本授权。我正在使用 gate 进行 laravel 授权。 表结构 User Table, Permission Table, Role, role_permissi
据我所知,我们有一个Youtube API,可通过使用以下API详细信息来获取基于某个地区的趋势YouTube视频: https://developers.google.com/youtube/v3/
我有一个看起来像这样的出租车列表: 1204725 2162 1300163 420247 我希望从上面的taxids中按顺序获得一个带有分类ID的文件: kingdom_id phylum
我一直在尝试弄清楚如何制作“ HitTest 门帖子”,其中帖子是按在最短的时间内获得最多支持排序的。 我有 2 个数据库表: 有趣的帖子: fun_post_upvotes: 我的最新代码仍然不起作
如何通过 Windows API 调用打开 CD/DVD 门? 最佳答案 如果您使用 .NET,这将起作用: http://www.dotnetspider.com/resources/15834-e
我们的核心目标是: 使用图像处理来读取/扫描建筑平面图图像(从 CAD 软件导出) 使用图像处理来读取/扫描建筑平面图图像(从 CAD 软件导出)提取各种直线和曲线,将它们分组为结构实体,如墙、柱、梁
给定 n 个元素 1,2,.........,n 上的二叉搜索树的后序遍历 P。您必须确定以 P 作为其后序遍历的唯一二叉搜索树。执行此操作的最有效算法的时间复杂度是多少? (a) theeta(lo
根据定义,门 1/sqrt(5) (I + 2iZ) 应作用于量子位 a|0> + b|1> 以将其转换为 1/sqrt (5) ((1+2i)a|0> + (1-2i)b|1>) 但每个 RUS 步
我有物种的分类 ID,我可以从 NCBI ( https://www.ncbi.nlm.nih.gov/Taxonomy/TaxIdentifier/tax_identifier.cgi ) 获得物种
我是一名优秀的程序员,十分优秀!