基于BFS的腐烂橘子的问题(题源leetcode)

题目大意:

在给定的网格中,每个单元格可以有以下三个值之一:

值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,任何与腐烂的橘子(在 4 个正方向上)相邻的新鲜橘子都会腐烂。

返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1。

示例 1:
输入:[[2,1,1],[1,1,0],[0,1,1]]
输出:4
图例解释

示例 2:
输入:[[2,1,1],[0,1,1],[1,0,1]]
输出:-1
解释:左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个正向上。

示例 3:

输入:[[0,2]]
输出:0
解释:因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0 。

提示:

1 <= grid.length <= 10
1 <= grid[0].length <= 10
grid[i][j] 仅为 0、1 或 2

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rotting-oranges
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

为了表达的简洁,这里将整个函数的功能划分为小函数

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

struct Node
{
	int x;
	int y;
	int level;//这是必要,因为需要记录到底是第几层 
	Node(int a,int b,int c)
	{
		x=a;
		y=b;
		level=c;
	}
}; 

bool unique=true;
int number=0;
int vis[10][10]={false};
queue<Node> bad;
int shiftx[4]={0,1,0,-1};//以下的两个都是控制方向的数组,目的是可以直接使用循环来遍历四个方向
int shifty[4]={1,0,-1,0};

void printNow(vector<vector<int> > grid)
{
	for(int i=0;i<grid.size();i++)
	{
		for(int j=0;j<grid[i].size();j++)
		{
			cout<<grid[i][j]<<" ";
		}
		cout<<endl;
	}
	cout<<endl;
}//这个函数只是用来检验输入的,解题步骤中不需要

void Initial(vector<vector<int> >& grid)//这个函数的目的是检验输入的数组是否一开始就可以判断;以及将腐烂的橘子给放到队列中去
{
	for(int i=0;i<grid.size();i++)
	{
		for(int j=0;j<grid[i].size();j++)
		{
			if(grid[i][j]==1)
			{
				unique=false;
			}
			if(grid[i][j]==2)
			{
				Node temp(i,j,0);
				bad.push(temp);
			}
		}
	}
}

void Search(vector<vector<int> >& grid)//这个就是腐烂的橘子不断扩散的过程
{
	while(!bad.empty())
	{
		Node temp1=bad.front();
		bad.pop();
		int m=grid.size();
		int n=grid[temp1.x].size();
		int lev=temp1.level;
		int tep=number;
		number=lev;
		if(number!=tep)
		{
			printNow(grid);//这里只是为了检验,答案中需要去掉
		}
		for(int i=0;i<4;i++)//遍历四个方向
		{
			int xx=temp1.x+shiftx[i];
			int yy=temp1.y+shifty[i];
			//一定要判断清楚到底是哪里越界了 
			if(xx<0||xx>=m||yy<0||yy>=n)//三种情况,越界的情况,1的情况,0和2的情况 
			{
				continue;
			}
			else
			{
				if(grid[xx][yy]==1)
				{
					grid[xx][yy]=2;
					int temperary=lev+1;
					Node a(xx,yy,temperary);
					bad.push(a);
				}
				else
				{
					continue;
				}
			}
		}
	}
}

int Check(vector<vector<int> >& grid)//作用是检验search之后的数组,并且返回-1或者需要的分钟
{
	
	for(int i=0;i<grid.size();i++)
	{
		for(int j=0;j<grid[i].size();j++)
		{
			if(grid[i][j]==1)
			{
				return -1;
			}
		}
	}
	return number;
}
int orangesRotting(vector<vector<int> >& grid)//主要作用函数
{
	Initial(grid);
	printNow(grid);
	if(unique==true) return 0;//特判 
	Search(grid);//改变number的值 
	int ans=Check(grid);//用于返回number数或-1 
	return ans;
} 

int main()
{
	vector< vector<int> > grid(3,vector<int>(3,0));
	grid[0][0]=2;
	grid[0][1]=1;
	grid[0][2]=1;
	grid[1][0]=1;
	grid[1][1]=1;
	grid[1][2]=0;
	grid[2][0]=0;
	grid[2][1]=1;
	grid[2][2]=1;
	
	int ans=orangesRotting(grid);
	cout<<ans;
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值