简体   繁体   English

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

[英]Why do I have to use do-while loop for this maze?

I found this question [here]: https://leetcode.com/problems/the-maze/ If you can't open the question, Here is the image of the problem:我在[这里]找到了这个问题: https : //leetcode.com/problems/the-maze/如果你无法打开问题,这是问题的图像:

在此处输入图片说明

Here is my code:这是我的代码:

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

I referenced the solution while I was writing this code.我在编写此代码时参考了解决方案。 Why do I need do-while in the code?为什么我需要在代码中使用 do-while? I tried to use only while loop and it got wrong answer.我试图只使用 while 循环,但得到了错误的答案。

As explained in the link posted by Ole VV while loop checked the condition prior to executing the block.正如Ole VV发布的链接中所述, while循环在执行块之前检查了条件。 do-while checks the condition after executing the block. do-while在执行块后检查条件。
This means that changing from one form to another, requires changing the condition.这意味着从一种形式变为另一种形式需要改变条件。 However, before you attempt to compare two solutions, one implemented using while and another using do-while , make sure that you start with a valid solution.但是,在您尝试比较两种解决方案之前,一种是使用while实现的,另一种是使用do-while ,请确保您从有效的解决方案开始。
The posted solution returns false if maze is changed to:如果 maze 更改为:

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

(using the same start and end points). (使用相同的起点和终点)。
To my understanding it should return true.据我了解,它应该返回 true。

This solution seems to do better (may need some more testing though):这个解决方案似乎做得更好(虽然可能需要更多的测试):

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

Why do I have to use do-while loop for this maze?为什么我必须在这个迷宫中使用 do-while 循环?

You don't have to.你不必。 Ever.曾经。

As @brandonx states:正如@brandonx 所说:

do ... while loops are typically used when you want to ensure that the loop always executes at least once. do ... while循环通常用于确保循环始终至少执行一次。

(Emphasis added!) (重点加了!)

And if this is what you want to happen, using a do ... while loop will often give you more readable code.如果这是你想要发生的事情,使用do ... while循环通常会给你更多可读的代码。

However, you don't have to do it this way.但是,您不必这样做。 Any do ... while loop can be rewritten as a while loop and vice-versa .任何do ... while循环都可以重写为while循环,反之亦然 For example,例如,

do { statement; } while (condition)

can be rewritten as:可以改写为:

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

And we can transform in the other direction:我们可以向另一个方向转换:

while (condition) { statement; }

can be rewritten as:可以改写为:

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

This doesn't directly answer your question about what was wrong with your code.这并不能直接回答您关于代码有什么问题的问题。 But it you understand the relationship between while and do ... while , it will help you understand why it makes a difference which one you use.但是,如果您了解whiledo ... while之间的关系,它将帮助您了解为什么使用哪个会有所不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM