leetcode 994 腐烂的橘子

先给出题目:
在给定的网格中,每个单元格可以有以下三个值之一:
值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,任何与腐烂的橘子(在 4 个正方向上)相邻的新鲜橘子都会腐烂。
返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rotting-oranges
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

给出思路:
解题首要目的,先把问题解决,不论方法。首先考虑到,直接模拟腐烂的过程,最后统计腐烂的结果。考虑以下几种情况:一个网格里是腐烂的橘子,它只能腐化上下左右四个方向格子装有的新鲜橘子;如果腐烂的橘子周围没有新鲜的橘子,则无法传播腐化;当所有腐烂的橘子都无法传播腐化时,结束模拟过程,开始统计结果。
下面给出代码:

class Solution {
    public  int orangesRotting(int[][] grid) {
		int count = 0;
		while (true) {
			if (haveNextStep(grid)) {
				grid = rotting(grid);
				count++;
			} else {
				if (isRotted(grid)) {
					return count;
				} else {
					return -1;
				}
			}
		}

	}
	//判断腐化能否继续进行下去
	public  Boolean haveNextStep(int[][] grid) {
		int row = grid.length;
		int col = grid[0].length;
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				if(grid[i][j] == 2 ) {
					if (i - 1 >= 0 && grid[i - 1][j] == 1 ||
							i + 1 < row && grid[i + 1][j] == 1 ||
							j - 1 >= 0 && grid[i][j - 1] == 1||
							j + 1 < col && grid[i][j + 1] == 1) {
						return true;
					}
					
				}
			}
		}
		return false;
	}
	//对结果进行判断,是否全部新鲜橘子被腐化
	public  Boolean isRotted(int[][] grid) {
		int row = grid.length;
		int col = grid[0].length;
		int fresh = 0;
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				if (grid[i][j] == 1) {
					fresh++;
				}		
			}
		}
		
		if(fresh > 0)
			return false;
		return true;
	}
	//模拟一步腐化过程,也就是一分钟
	public  int[][] rotting(int[][] grid) {
		int row = grid.length;
		int col = grid[0].length;
		int[][] temp = new int[row][col];
		// copy
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				temp[i][j] = grid[i][j];
			}
		}
		// rotting
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				if (grid[i][j] == 2) {
					if (i - 1 >= 0 && grid[i - 1][j] == 1) {
						temp[i - 1][j] = 2;
					}
					if (i + 1 < row && grid[i + 1][j] == 1) {
						temp[i + 1][j] = 2;
					}
					if (j - 1 >= 0 && grid[i][j - 1] == 1) {
						temp[i][j - 1] = 2;
					}
					if (j + 1 < col && grid[i][j + 1] == 1) {
						temp[i][j + 1] = 2;
					}
				}
			}
		}
		return temp;
	}
}

这是能够直接想到的方法,它解决了问题,初步到达了我们的目标。但是明显它不够效率,冗余代码也较多。所以我们要思考有没有更好的方法去解决这个问题。
算法课学的东西我都忘得差不多了,哈哈,我想不到更好的办法了。嗯,只能借鉴一下其他人的思想了。等我彻底搞懂了再补充上来。
看了看官方的解答,感觉还是这个思路,我把代码改了改,减少了代码冗余度,时间复杂度并没有降低,运行时间跟以前一样都是4ms。
代码如下:

class Solution {
    public int orangesRotting(int[][] grid) {
        //存四个方向坐标,省的整四个if导致重复代码多
		int[] dr = new int[]{-1, 0, 1, 0};
	    int[] dc = new int[]{0, -1, 0, 1};
	    
		Queue<Integer> queue = new ArrayDeque<Integer>();
		Map<Integer,Integer> depth = new HashMap<Integer, Integer>();
		int row = grid.length;
		int col = grid[0].length;
		for (int i = 0; i < row; i++) {
			for(int j = 0; j < col; j++) {
				if (grid[i][j] == 2) {
					int code = i * col + j;
					queue.add(code);
					depth.put(code, 0);
				}
			}
		}
		
		int rs = 0;
		while(!queue.isEmpty()) {
			int code = queue.remove();
			int r = code / col;
			int c = code % col;
			for(int k = 0 ; k < 4; k++) {
				int nr = r + dr[k];
				int nc = c + dc[k];
				if(nr >=0 && nr < row && nc >= 0 && nc < col && grid[nr][nc] == 1) {
					grid[nr][nc] = 2;
					int ncode = nr * col + nc;
					queue.add(ncode);
					depth.put(ncode, depth.get(code) + 1);
					rs = depth.get(ncode);
				}
			}
			
		}
		
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				if (grid[i][j] == 1) {
					return -1;
				}				
			}
		}
		
		return rs;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值