240
笔下虽有千言,胸中实无一策

30 Day Challenge Day 18 | Leetcode 994. Rotting Oranges

题解

Medium

BFS

这道题有点类似Number of Islands,可以用DFS或者BFS,但我觉得要更难一点,因为涉及到更新记忆数组。下面我的做法是用BFS(今天主要是想要练习BFS的套路)。

看了官方给出的答案,我的做法还是有几点值得改进的,其中一点是避免使用了记忆数组。因为从根本上来说,BFS是能够保证最短路径(这里是最短时间)的,一般用DFS的时候才需要配合使用记忆数组。我这里显然是没有在第一步把所有等于2的位置都放进队列中。可能是受Number of Islands那道题的影响。

class Solution {
public:
    int orangesRotting(vector<vector<int>>& grid) {
        if(grid.empty()) return 0;
        
        int min_minutes = 0;
        
        vector<vector<int>> memo(grid.size(), vector<int>(grid[0].size(), INT_MAX));
        
        int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        
        for(int i = 0; i < grid.size(); i++) {
            for(int j = 0; j < grid[0].size(); j++) {
                if(grid[i][j] == 2) {
                    
                    vector<vector<int>> temp = grid;
                    
                    int minutes = 0;

                    queue<vector<int>> q;
                    q.push({i, j});

                    while(!q.empty()) {
                        int sz = q.size();
                        minutes++;
                        for(int i = 0; i < sz; i++) {
                            auto t = q.front();
                            q.pop();
                            for(int k = 0; k < 4; k++) {
                                int x = t[0] + dirs[k][0];
                                int y = t[1] + dirs[k][1];

                                if(x < 0 || x >= temp.size() || y < 0 || y >= temp[0].size()
                                  || temp[x][y] == 0)
                                    continue;

                                if(temp[x][y] == 1) {
                                    temp[x][y] = 2;
                                    memo[x][y] = min(memo[x][y], minutes);
                                    q.push({x, y});
                                }
                            }
                        }
                    }
                }
            }
        }
        
        for(int i = 0; i < grid.size(); i++) {
            for(int j = 0; j < grid[0].size(); j++) {
                if(grid[i][j] == 1) {
                    if(memo[i][j] == INT_MAX) return -1;
                    min_minutes = max(min_minutes, memo[i][j]);
                }
            }
        }
        
        return min_minutes;
    }
};

下面根据官方答案,改进了上述代码。

class Solution {
public:
    int orangesRotting(vector<vector<int>>& grid) {
        if(grid.empty()) return 0;
        
        int minutes = -1, num_of_fresh = 0;
        
        queue<vector<int>> q;
        
        for(int i = 0; i < grid.size(); i++) {
            for(int j = 0; j < grid[0].size(); j++) {
                if(grid[i][j] == 2) {
                    q.push({i, j});
                } else if (grid[i][j] == 1) {
                    num_of_fresh++;
                }
            }
        }
        
        if(num_of_fresh == 0) return 0;
        
        int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

        while(!q.empty()) {
            int sz = q.size();
            minutes++;
            for(int i = 0; i < sz; i++) {
                auto t = q.front();
                q.pop();
                for(int k = 0; k < 4; k++) {
                    int x = t[0] + dirs[k][0];
                    int y = t[1] + dirs[k][1];

                    if(x < 0 || x >= grid.size() || y < 0 || y >= grid[0].size()
                      || grid[x][y] == 0)
                        continue;

                    if(grid[x][y] == 1) {
                        grid[x][y] = 2;
                        num_of_fresh--;
                        q.push({x, y});
                    }
                }
            }
        }
        
        return num_of_fresh == 0 ? minutes : -1;
    }
};
posted @ 2020-10-03 04:35  CasperWin  阅读(58)  评论(0编辑  收藏  举报