Почему я должен использовать цикл do-while для этого лабиринта? - PullRequest
0 голосов
/ 06 апреля 2019

Я нашел этот вопрос [здесь]: 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;
    }
}

Я ссылался на решение, пока писал этот код.Зачем мне нужно делать в то время как в коде?Я пытался использовать только цикл, и он получил неправильный ответ.

Ответы [ 2 ]

0 голосов
/ 06 апреля 2019

Почему я должен использовать цикл 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, это поможет вам понять, почему имеет значение, какой вы используете.

0 голосов
/ 06 апреля 2019

Как объяснено в ссылке, опубликованной Ole VV 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;
}
...