考察知识点:队列、广度优先搜索

题目分析:

可以通过广度优先搜索,对每一个生病的牛旁边的健康的牛进行染病。如果在将所有生病的牛旁边的健康的牛染病之后,仍有健康的牛,那么说明不能将所有牛染病。如果健康的牛的数量本身就是0,那么等待0分钟就能将所有牛染病。

在广度优先搜索时,要先记录当前队列中的长度。因为每一分钟内不能访问新加入队列中的牛。再访问每一个染病的牛时,看它的上下左右四个方向上有没有健康的牛,如果有就将健康的牛染病,并记录健康牛的数量减1。当健康牛的数量为0时返回需要的分钟数。

所用编程语言:C++

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pasture int整型vector<vector<>> 
     * @return int整型
     */
    int healthyCowsII(vector<vector<int> >& pasture) {
        // write code here
        int m = pasture.size();
        int n = pasture[0].size();
        int healthyCowsNum = 0;
        int k = 0;
        queue<pair<int, int >> illcows;
        
        int dx[4] = {-1, 0, 1, 0};
        int dy[4] = {0, 1, 0, -1};

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (pasture[i][j] == 0)
                    continue;
                if (pasture[i][j] == 2) 
                    illcows.push({i, j});
                else 
                    healthyCowsNum++;
            }
        }

        if (healthyCowsNum == 0) 
            return 0;

        while (!illcows.empty()) {
            k++;
            int size = illcows.size();
            while (size--) {
                pair<int, int> illcow = illcows.front();
                illcows.pop();
                int row = illcow.first;
                int col = illcow.second;
                for (int i = 0; i < 4; i++) {
                    int irow = row + dx[i];
                    int icol = col + dy[i];
                    if (irow >= 0 && irow < m && icol >= 0 && icol < n && pasture[irow][icol] == 1) {
                        illcows.push({irow, icol});
                        healthyCowsNum--;
                        pasture[irow][icol] = 2;
                        if (healthyCowsNum == 0) 
                            return k;
                    }
                }
            }
        }
        return -1;
    }
};