leetcode994. Rotting Oranges

题目:题目链接

思路:直接bfs就好。每一分钟都拓展当前所有的腐烂橙子,然后直到不能拓展,再看是否还有新鲜橙子。看代码吧:

class Solution {
public:
	int m, n;
	bool isInBoard(int x, int y) {//判断是否在网格内
		return (x < m&& x >= 0) && (y < n&& y >= 0);
	}
	int orangesRotting(vector<vector<int>>& grid) {
		m = grid.size();
		n = grid[0].size();
		int cnt = 0, time = 0;//cnt表示新鲜橙子的个数,time表示分钟数
		queue<pair<int, int> >q;//存放每个腐烂橙子的坐标
		vector<vector<int> >vis(m, vector<int>(n, 0));//标记该坐标是否访问过
		vector<vector<int> >dis = { {0,-1},{0,1},{1,0},{-1,0} };//可以向四个方向拓展
		for (int i = 0; i < m; ++i) {//查找新鲜橙子和腐烂橙子
			for (int j = 0; j < n; ++j) {
				if (grid[i][j] == 1) cnt++;
				if (grid[i][j] == 2) {//把腐烂橙子放入队列q中
					q.push(make_pair(i, j));
					vis[i][j] = 1;
				}
			}
		}
		if (cnt == 0) return 0;//没有新鲜橙子
		while (!q.empty()) {
			int size = q.size();//当前队列的大小
			for (int j = 0; j < size; ++j) {//在每一分钟把当前队列中的所有腐烂橙子都进行拓展
				auto tmp = q.front();
				q.pop();
				for (int i = 0; i < dis.size(); ++i) {
					int now_x = tmp.first + dis[i][0];
					int now_y = tmp.second + dis[i][1];
					if (isInBoard(now_x, now_y) && !vis[now_x][now_y]) {//坐标合法,且没有被拓展过
						if (grid[now_x][now_y] == 1) {//因为新鲜橙子可以变成腐烂的,空的和已腐烂的都无变化
							grid[now_x][now_y] = 2;
							cnt--;
							q.push(make_pair(now_x, now_y));
						}
						vis[now_x][now_y] = 1;//对于当前拓展的结点不管是0,1,2都标记为访问,避免重复访问
					}
				}
			}
			time++;//分钟数增加
		}
		if (cnt == 0) return time - 1;//注意:这里为什么time-1,而不是time。因为当新鲜橙子都腐烂时队列时不为空的。只有等最后一批腐烂橙子拓展完才为空。
		return -1;
	}
};

注意:time最后要减1,因为while循环终止条件是队列q为空,当最后一个新鲜橙子变成腐烂橙子时,队列是不为空的,还有这个腐烂橙子,直至下一秒这个腐烂橙子也拓展完。所以time比实际时间多1。当然在while中加一个cnt>0也可以。

搞定。加油加油加油加油加油加油!!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值