LeetCode-542. 01 Matrix (JAVA)零一矩阵

该博客详细介绍了LeetCode 542题目的解决方案,即如何找到矩阵中每个单元格到最近0的距离。通过将1元素设置为最大值,使用BFS而非DFS策略,从0元素开始传播影响,逐步更新矩阵,确保正确计算相邻1元素的距离。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

542. 01 Matrix

Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell.

The distance between two adjacent cells is 1.

Example 1:
Input:

0 0 0
0 1 0
0 0 0
Output:
0 0 0
0 1 0
0 0 0

Example 2:
Input:

0 0 0
0 1 0
1 1 1
Output:
0 0 0
0 1 0
1 2 1

Note:

  1. The number of elements of the given matrix will not exceed 10,000.
  2. There are at least one 0 in the given matrix.
  3. The cells are adjacent in only four directions: up, down, left and right.

参考:http://blog.youkuaiyun.com/u014688145/article/details/64126559

解决思路

  1. 对待求矩阵进行一次变换,遇0元素不变,遇1元素设为最大值。
    00inf0infinf00inf

inf在此处表示无穷,在Java代码中,用Integer.MAX_VALUE来表示。在对它变换的同时,由于已经扫描了一遍矩阵,在此过程中还需要记录所有0元素的row,col值,并放入一个队列中。

接下来是求解的核心了,我们只需要寻找到一种机制能够准确更新该数组就可以了,并且它的更新规则符合题意。刚才的dfs是在一个方向上遍历到底,没法拐弯,问题的关键在于隔壁的1元素是否携带了有效信息供当前节点参考!很明显,dfs方案一条路走到底,每个1元素忽略另外三个方向的信息,所以自然而然无法求出正确的。

而再来看看bfs,用形象的比喻来描述这道题的话,就是一颗石头扔入湖中时,它的影响波及周围,且向四周不断传播它的影响。所以该算法的思想,就是首先把这些石头找出来咯【0元素】,更新规则是,一旦碰到【inf】,我就设一个该【0元素】对【inf】的影响值,此处为1。但由于【0元素】的影响是传递的,所以受它影响的【inf】节点必须得放入队列中,计算下次影响值。碰到【inf】,则+1,但前提是当前【inf】节点的值大于原先的值+1。

第二次更新:

00101inf001

0元素周围的元素均被波及,接下来就是1元素的传递,传递的还是0元素的影响。

第三次更新:

001012001

	public List<List<Integer>> updateMatrix(List<List<Integer>> matrix) {
		if (matrix == null || matrix.size() == 0)
			return matrix;
		int m = matrix.size();
		int n = matrix.get(0).size();
		Queue<int[]> q = new LinkedList<>();
		for (int i = 0; i < m; i++)
			for (int j = 0; j < n; j++) {
				// 把0元素加入队列中,以备波及影响周围元素
				if (matrix.get(i).get(j) == 0)
					q.offer(new int[] { i, j });
				else
					// 设为最大值,方便求0元素影响值
					matrix.get(i).set(j, Integer.MAX_VALUE);
			}
		// 上下左右
		int[][] dirs = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
		while (!q.isEmpty()) {
			int cell[] = q.poll();
			for (int[] d : dirs) {
				int row = cell[0] + d[0];
				int col = cell[1] + d[1];
				if (row < 0 || row >= m || col < 0 || col >= n)
					continue;
				// 上下左右取到的值
				int value = matrix.get(row).get(col);
				int tmp = matrix.get(cell[0]).get(cell[1]) + 1;
				// 如果value小,那说明之前已经更新过,不是max
				if (value <= tmp)
					continue;
				q.offer(new int[] { row, col });
				matrix.get(row).set(col, tmp);

			}

		}

		return matrix;
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值