1036. Escape a Large Maze

In a 1 million by 1 million grid, the coordinates of each grid square are (x, y).

We start at the source square and want to reach the target square.  Each move, we can walk to a 4-directionally adjacent square in the grid that isn't in the given list of blocked squares.

Return true if and only if it is possible to reach the target square through a sequence of moves.

 

Example 1:

Input: blocked = [[0,1],[1,0]], source = [0,0], target = [0,2]
Output: false
Explanation: The target square is inaccessible starting from the source square, because we can't walk outside the grid.

Example 2:

Input: blocked = [], source = [0,0], target = [999999,999999]
Output: true
Explanation: Because there are no blocked cells, it's possible to reach the target square.

 

Constraints:

  • 0 <= blocked.length <= 200
  • blocked[i].length == 2
  • 0 <= blocked[i][j] < 10^6
  • source.length == target.length == 2
  • 0 <= source[i][j], target[i][j] < 10^6
  • source != target

Rust Solution

struct Solution;

use std::collections::HashSet;
use std::collections::VecDeque;

impl Solution {
    fn is_escape_possible(blocked: Vec<Vec<i32>>, source: Vec<i32>, target: Vec<i32>) -> bool {
        Self::bfs(&blocked, source.clone(), target.clone()) && Self::bfs(&blocked, target, source)
    }

    fn bfs(blocked: &[Vec<i32>], source: Vec<i32>, target: Vec<i32>) -> bool {
        let mut visited: HashSet<Vec<i32>> = HashSet::new();
        let mut queue: VecDeque<Vec<i32>> = VecDeque::new();
        let n = 1_000_000;
        for point in blocked {
            visited.insert(point.clone());
        }
        queue.push_back(source.clone());
        visited.insert(source);
        let mut step = 0;
        while let Some(point) = queue.pop_front() {
            step += 1;
            if point == target || step == 20000 {
                return true;
            }
            let i = point[0];
            let j = point[1];
            let up = vec![i - 1, j];
            let left = vec![i, j - 1];
            let down = vec![i + 1, j];
            let right = vec![i, j + 1];
            if i > 0 && visited.insert(up.clone()) {
                queue.push_back(up);
            }
            if j > 0 && visited.insert(left.clone()) {
                queue.push_back(left);
            }
            if i + 1 < n && visited.insert(down.clone()) {
                queue.push_back(down);
            }
            if j + 1 < n && visited.insert(right.clone()) {
                queue.push_back(right);
            }
        }
        false
    }
}

#[test]
fn test() {
    let blocked = vec_vec_i32![[0, 1], [1, 0]];
    let source = vec![0, 0];
    let target = vec![0, 2];
    let res = false;
    assert_eq!(Solution::is_escape_possible(blocked, source, target), res);
    let blocked = vec_vec_i32![];
    let source = vec![0, 0];
    let target = vec![999999, 999999];
    let res = true;
    assert_eq!(Solution::is_escape_possible(blocked, source, target), res);
}

Having problems with this solution? Click here to submit an issue on github.