为什么我必须为此迷宫使用do-while循环?

时间:2019-04-06 01:54:26

标签: java algorithm breadth-first-search maze

我在[这里]找到了这个问题: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;
    }
}

我在编写此代码时引用了解决方案。为什么我需要在代码中执行操作?我尝试仅使用while循环,但答案错误。

2 个答案:

答案 0 :(得分: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},
    };

(使用相同的起点和终点)。
据我了解,它应该返回true。

此解决方案似乎更好(尽管可能需要更多测试):

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

答案 1 :(得分:0)

  

为什么我必须为此迷宫使用do-while循环?

您不必。曾经。

@brandonx指出:

  如果要确保循环始终至少执行一次,通常使用

do ... while循环。

(已添加强调!)

如果这是您要发生的情况,则使用do ... while循环通常会使您的代码更具可读性。

但是,您不必这样做。任何do ... while循环都可以重写为while循环, vice-versa 。例如,

do { statement; } while (condition)

可以改写为:

boolean firstTime = true;
while (firstTime || condition) {
    firstTime = false;
    statement;
}

我们可以朝另一个方向变换:

while (condition) { statement; }

可以改写为:

if (condition) {
    do { statement; } while (condition)
}

这不会直接回答您的有关代码错误的问题。但是您了解了whiledo ... while之间的关系,这将帮助您理解为什么使用哪一种会有所不同。