为什么我必须在这个迷宫中使用do-while循环?

问题描述 投票:-2回答:2

我发现这个问题[这里]:https://leetcode.com/problems/the-maze/如果你无法打开问题,这是问题的图像:

enter image description here

这是我的代码:

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循环,它得到了错误的答案。

java algorithm breadth-first-search maze
2个回答
0
投票

正如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;
}

0
投票

为什么我必须在这个迷宫中使用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)
}

这并不直接回答您关于代码错误的问题。但是你了解whiledo ... while之间的关系,它将帮助你理解为什么它会对你使用哪一个产生影响。

© www.soinside.com 2019 - 2024. All rights reserved.