我发现这个问题[这里]:https://leetcode.com/problems/the-maze/如果你无法打开问题,这是问题的图像:
这是我的代码:
class Solution {
public boolean hasPath(int[][] maze, int[] start, int[] destination) {
ArrayDeque<int[]> queue = new ArrayDeque<>();
int[][] directions = {{1,0},{-1,0},{0,1},{0,-1}};
queue.offer(start);
while(!queue.isEmpty()) {
int [] loc = queue.poll();
int x = loc[0];
int y = loc[1];
if(x == destination[0] && y == destination[1])
return true;
for(int[] dir : directions) {
do{
x += dir[0];
y += dir[1];
}while(x >= 0 && y >= 0 && x < maze.length && y < maze[0].length && maze[x][y] == 0);
x -= dir[0];
y -= dir[1];
if(maze[x][y] != 2) {
queue.offer(new int[] {x,y});
maze[x][y] = 2;
}
}
}
return false;
}
}
我在编写此代码时引用了该解决方案。为什么我需要代码中的do-while?我试图只使用while循环,它得到了错误的答案。
正如Ole V.V发布的链接中所解释的那样,while
循环在执行块之前检查了条件。 do-while
在执行块后检查条件。
这意味着从一种形式转换到另一种形式需要改变条件。但是,在您尝试比较两个解决方案之前,一个使用while
实现,另一个使用do-while
解决方案,请确保您使用有效的解决方案。
如果迷宫更改为:已发布的解决方案将返回false:
int[][] maze = {
{0, 0, 1, 0, 0},
{0, 1, 0, 0, 0},
{0, 0, 0, 1, 0},
{1, 1, 0, 1, 1},
{0, 0, 0, 0, 0},
};
(使用相同的起点和终点)。 根据我的理解,它应该回归真实。
这个解决方案似乎做得更好(可能需要更多测试):
public boolean hasPath(int[][] maze, int[] start, int[] destination) {
ArrayDeque<int[]> queue = new ArrayDeque<>();
int[][] directions = {{1,0},{-1,0},{0,1},{0,-1}};
queue.offer(start);
while(!queue.isEmpty()) {
int [] loc = queue.poll();
int x = loc[0];
int y = loc[1];
if(x == destination[0] && y == destination[1]){
return true;
}
for(int[] dir : directions) {
while(x+dir[0]>= 0 && y+dir[1] >= 0 && x+dir[0] < maze.length && y+dir[1] <
maze[0].length && maze[x+dir[0]][y+dir[1]] == 0){
x += dir[0];
y += dir[1];
if(!queue.contains(new int[] {x,y})) {
queue.offer(new int[] {x,y});
maze[x][y] = 2;
}
}
}
}
return false;
}
为什么我必须在这个迷宫中使用do-while循环?
你不必。永远。
正如@brandonx所述:
当您希望确保循环始终至少执行一次时,通常会使用
do ... while
循环。
(强调补充!)
如果这是您想要发生的事情,使用do ... while
循环通常会为您提供更易读的代码。
但是,您不必这样做。任何do ... while
循环都可以重写为while
循环,反之亦然。例如,
do { statement; } while (condition)
可以改写为:
boolean firstTime = true;
while (firstTime || condition) {
firstTime = false;
statement;
}
我们可以转向另一个方向:
while (condition) { statement; }
可以改写为:
if (condition) {
do { statement; } while (condition)
}
这并不直接回答您关于代码错误的问题。但是你了解while
和do ... while
之间的关系,它将帮助你理解为什么它会对你使用哪一个产生影响。