Start learning free

LESSON 564 OF 671 · GRAPHS

01 Matrix - Java Solution and Time Complexity Analysis

Practice O(n * m) Read the full explanation

You get a grid of 0s and 1s. It is an array of rows, and each row is an array of integers.

Return a grid of the same size. Each cell in it holds the number of steps to the closest 0.

A step moves one cell up, down, left or right. You can't move diagonally. A cell that holds 0 is 0 steps away.

 

Example 1:

Input:
[[1,0,1,1],
 [1,1,1,0],
 [0,1,1,1]]

Output:
[[1,0,1,1],
 [1,1,1,0],
 [0,1,2,1]]

Explanation: Each 1 that touches a 0 gets 1.
The 1 at row 2, column 2 (counting from 0) touches no 0.
Its closest 0 is 2 steps away: up, then right.

Example 2:

Input:
[[1,1,0,1,1,1]]

Output:
[[2,1,0,1,2,3]]

Explanation: There is one row with one 0.
The count grows by 1 with each cell away from it.

Example 3:

Input:
[[1,1,1],
 [1,1,1],
 [1,1,0]]

Output:
[[4,3,2],
 [3,2,1],
 [2,1,0]]

Explanation: The only 0 is in the bottom-right corner.
The top-left cell is 2 rows up and 2 columns left of it.
So it is 2 + 2 = 4 steps away.

 

Constraints:

  • 1 to 10,000 cells in all.
  • The grid can be 100 rows of 100 or one row of 10,000.
  • All rows have the same length.
  • Every cell is 0 or 1.
  • At least one cell is 0.
STEP 1 OF 15
    Ctrl + Enter to check

    JAVA · GRAPHS

    01 Matrix in Java, explained

    Understanding the Problem

    The core challenge of this problem is to efficiently compute the shortest distance from each cell to the nearest 0. This problem is significant in various applications such as image processing, pathfinding in grids, and more. A common pitfall is to use a naive approach that results in high time complexity, making it impractical for larger matrices.

    Approach

    To solve this problem, we can use a multi-source Breadth-First Search (BFS) approach. The idea is to start from all the 0s simultaneously and propagate the distance to the 1s. This ensures that each cell is updated with the shortest distance to a 0.

    Naive Solution

    A naive solution would involve iterating over each cell and performing a BFS or DFS to find the nearest 0. This approach is not optimal as it results in a time complexity of O((m*n)^2), where m and n are the dimensions of the matrix.

    Optimized Solution

    The optimized solution involves using a queue to perform a BFS starting from all 0s. This ensures that each cell is visited in the shortest path order. The time complexity of this approach is O(m*n), which is much more efficient.

    Algorithm

    1. Initialize a queue and enqueue all cells containing 0. Set their distance to 0.

    2. For each cell containing 1, set its distance to infinity initially.

    3. Perform BFS from the queue, updating the distance of each cell based on its neighbors.

    4. Continue until the queue is empty.

    Code Implementation

    import java.util.LinkedList;
    import java.util.Queue;
    
    public class Solution {
        public int[][] updateMatrix(int[][] matrix) {
            int rows = matrix.length;
            int cols = matrix[0].length;
            int[][] dist = new int[rows][cols];
            Queue queue = new LinkedList<>();
    
            // Initialize distances and queue
            for (int i = 0; i < rows; i++) {
                for (int j = 0; j < cols; j++) {
                    if (matrix[i][j] == 0) {
                        dist[i][j] = 0;
                        queue.offer(new int[]{i, j});
                    } else {
                        dist[i][j] = Integer.MAX_VALUE;
                    }
                }
            }
    
            // Directions for moving in the matrix
            int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    
            // BFS to update distances
            while (!queue.isEmpty()) {
                int[] cell = queue.poll();
                int row = cell[0];
                int col = cell[1];
    
                for (int[] dir : directions) {
                    int newRow = row + dir[0];
                    int newCol = col + dir[1];
    
                    if (newRow >= 0 && newRow < rows && newCol >= 0 && newCol < cols) {
                        if (dist[newRow][newCol] > dist[row][col] + 1) {
                            dist[newRow][newCol] = dist[row][col] + 1;
                            queue.offer(new int[]{newRow, newCol});
                        }
                    }
                }
            }
    
            return dist;
        }
    }
    

    Complexity Analysis

    The time complexity of the optimized solution is O(m*n) because each cell is enqueued and dequeued at most once. The space complexity is also O(m*n) due to the distance matrix and the queue.

    Edge Cases

    1. A matrix with all 0s: The output should be the same as the input.

    2. A matrix with all 1s except one 0: The distances should increase as we move away from the 0.

    3. Large matrices: Ensure the solution handles the upper limit of 10,000 elements efficiently.

    Testing

    To test the solution comprehensively, consider the following test cases:

    • Small matrices with mixed 0s and 1s.
    • Edge cases with all 0s or all 1s except one 0.
    • Large matrices to test performance.

    Thinking and Problem-Solving Tips

    1. Break down the problem into smaller parts and understand the requirements.

    2. Consider different approaches and their time complexities.

    3. Use diagrams or pseudo-code to visualize the solution.

    4. Practice similar problems to improve problem-solving skills.

    Conclusion

    Understanding and solving the 01 Matrix problem helps in developing skills for grid-based problems and BFS/DFS algorithms. Practice and exploration of different approaches are key to mastering such problems.

    Additional Resources

    Keep going with Java650+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free