πŸ“ Problem Details

input matrix grid of size m * n each cell in grid can have three possible values: 0 β‡’ empty cell 1 β‡’ fresh orange 2 β‡’ rotten orange every minute any fresh orange that is 4-directionally adjacent to a rotten orange becomes rotten return the min number of minutes that must elapse until there are no cells with a fresh orange return -1 if impossible

πŸ’­What Were My Initial Thoughts?

Β  Β  Β  Β  // base case:
Β  Β  Β  Β  // init traversal variables
Β  Β  Β  Β  // init BFS queue
Β  Β  Β  Β  // first pass through to locate the positions of the rotten oranges
Β  Β  Β  Β  // push the location of each (2) into the queue
Β  Β  Β  Β  // init directions vector (up,down,left,right)
Β  Β  Β  Β  // BFS while the queue is not empty
Β  Β  Β  Β  Β  Β  // keep a counter for the number of minutes (1 min == 1 while loop iteration)
Β  Β  Β  Β  // get row and col variables from front of queue
Β  Β  Β  Β  // pop queue
Β  Β  Β  Β  // try move 1 in each direction from this rotten orange position
Β  Β  Β  Β  Β  Β  // if its a fresh orange, add it to the queue
Β  Β  Β  Β  Β  Β  // changes its value to rotten (2)
Β  Β  Β  Β  // return counter

πŸ’‘ Explanation of Solution

Similar to intuition with a few additional considerations:
- need to track fresh oranges in the first pass through
- if there are no fresh oranges at the start , return early with 0
- if fresh oranges remain after BFS, return -1 (some oranges can never rot)

βŒ› Complexity Analysis

Time Complexity: O(m*n)
Space Complexity: O(m*n)
	Worst case: all oranges are rotten , and we store every cell in the queue

πŸ’» Implementation of Solution

class Solution {
public:
    int orangesRotting(vector<vector<int>>& grid) {
        if (grid.empty()) return -1; // Edge case: empty grid
 
        int rows = grid.size();
        int cols = grid[0].size();
        queue<pair<int, int>> q; // BFS queue for rotten oranges
        int freshOranges = 0;    // Count of fresh oranges
        int minutes = 0;         // Time counter
 
        // Step 1: Initialize BFS queue with all rotten oranges & count fresh oranges
        for (int r = 0; r < rows; r++) {
            for (int c = 0; c < cols; c++) {
                if (grid[r][c] == 2) {
                    q.push({r, c});  // Add rotten orange to queue
                } else if (grid[r][c] == 1) {
                    freshOranges++;  // Count fresh oranges
                }
            }
        }
 
        // If no fresh oranges, return 0 immediately
        if (freshOranges == 0) return 0;
 
        // Step 2: BFS Directions (Right, Left, Down, Up)
        vector<pair<int, int>> directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
 
        // Step 3: BFS Processing
        while (!q.empty()) {
            int qSize = q.size();
            bool newRotten = false; // Track if any fresh oranges got rotten
 
            for (int i = 0; i < qSize; i++) {
                auto [row, col] = q.front();
                q.pop();
 
                for (auto [dr, dc] : directions) {
                    int newRow = row + dr;
                    int newCol = col + dc;
 
                    // Check bounds and if it's a fresh orange
                    if (newRow >= 0 && newRow < rows && newCol >= 0 && newCol < cols && grid[newRow][newCol] == 1) {
                        grid[newRow][newCol] = 2; // Rotten now
                        q.push({newRow, newCol}); // Add to queue
                        freshOranges--; // Decrease fresh count
                        newRotten = true;
                    }
                }
            }
 
            if (newRotten) minutes++; // Increase time only if an orange rotted this round
        }
 
        // If there are still fresh oranges left, return -1 (impossible to rot all)
        return freshOranges == 0 ? minutes : -1;
    }
};