286. Walls and Gates

You are given an m x n grid rooms initialized with these three possible values.

  • -1 A wall or an obstacle.
  • 0 A gate.
  • INF Infinity means an empty room. We use the value 231 - 1 = 2147483647 to represent INF as you may assume that the distance to a gate is less than 2147483647.

Fill each empty room with the distance to its nearest gate. If it is impossible to reach a gate, it should be filled with INF.

 

Example 1:

Input: rooms = [[2147483647,-1,0,2147483647],[2147483647,2147483647,2147483647,-1],[2147483647,-1,2147483647,-1],[0,-1,2147483647,2147483647]]
Output: [[3,-1,0,1],[2,2,1,-1],[1,-1,2,-1],[0,-1,3,4]]

Example 2:

Input: rooms = [[-1]]
Output: [[-1]]

Example 3:

Input: rooms = [[2147483647]]
Output: [[2147483647]]

Example 4:

Input: rooms = [[0]]
Output: [[0]]

 

Constraints:

  • m == rooms.length
  • n == rooms[i].length
  • 1 <= m, n <= 250
  • rooms[i][j] is -1, 0, or 231 - 1.

Rust Solution

struct Solution;

use std::collections::VecDeque;

impl Solution {
    fn walls_and_gates(rooms: &mut Vec<Vec<i32>>) {
        let n = rooms.len();
        if n == 0 {
            return;
        }
        let m = rooms[0].len();
        if m == 0 {
            return;
        }
        let mut queue: VecDeque<(usize, usize, i32)> = VecDeque::new();
        for i in 0..n {
            for j in 0..m {
                if rooms[i][j] == 0 {
                    queue.push_back((i, j, 0));
                }
            }
        }
        while let Some((i, j, dist)) = queue.pop_front() {
            let dist = dist + 1;
            if i > 0 && rooms[i - 1][j] > 0 && dist < rooms[i - 1][j] {
                rooms[i - 1][j] = dist;
                queue.push_back((i - 1, j, dist));
            }
            if j > 0 && rooms[i][j - 1] > 0 && dist < rooms[i][j - 1] {
                rooms[i][j - 1] = dist;
                queue.push_back((i, j - 1, dist));
            }
            if i + 1 < n && rooms[i + 1][j] > 0 && dist < rooms[i + 1][j] {
                rooms[i + 1][j] = dist;
                queue.push_back((i + 1, j, dist));
            }
            if j + 1 < m && rooms[i][j + 1] > 0 && dist < rooms[i][j + 1] {
                rooms[i][j + 1] = dist;
                queue.push_back((i, j + 1, dist));
            }
        }
    }
}

#[test]
fn test() {
    let inf = std::i32::MAX;
    let mut rooms = vec_vec_i32![
        [inf, -1, 0, inf],
        [inf, inf, inf, -1],
        [inf, -1, inf, -1],
        [0, -1, inf, inf]
    ];
    let res = vec_vec_i32![[3, -1, 0, 1], [2, 2, 1, -1], [1, -1, 2, -1], [0, -1, 3, 4]];
    Solution::walls_and_gates(&mut rooms);
    assert_eq!(rooms, res);
}

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