【搜索】B066_LC_最短的桥(FloodFill + bfs)

一、Problem

在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组。)

现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。

返回必须翻转的 0 的最小数目。(可以保证答案至少是 1。)

输入:[[0,1,0],[0,0,0],[0,0,1]]
输出:2

提示:

1 <= A.length = A[0].length <= 100
A[i][j] == 0 或 A[i][j] == 1

二、Solution

方法一:FloodFill + bfs

思路

由于 A 中只有两座岛,我们要用 bfs 的求两座岛的最短距离就必须要将两座岛区分开来

FloodFill 就是将某一个全 1 的连通块标记为 -1,然后 bfs 从这些 -1 的点出发,找到 1 时返回最短路即为答案

class Solution {
public:
	typedef pair<int, int> pii;
	int n, m, d[4][2] = { {1,0},{0,-1},{0,1},{-1,0} };
	queue<pii> q;
	// floodfill
	void dfs(int x, int y, vector<vector<int>>& A) {
		q.push({x, y});
		A[x][y] = -1;
		for (int k = 0; k < 4; k++) {
			int tx = x + d[k][0], ty = y + d[k][1];
			if (tx >= 0 && tx < n && ty >= 0 && ty < m && A[tx][ty] == 1)
				dfs(tx, ty, A);
		}
	}
    int shortestBridge(vector<vector<int>>& A) {
    	n = A.size(); m = A[0].size();
    	int finish = 0, op = 0;
    	for (int i = 0; i < n && !finish; i++)
		for (int j = 0; j < m; j++) if (A[i][j] == 1) {
			dfs(i, j, A);
			finish = 1;
			break;
		}

		while (!q.empty()) {
			int sz = q.size();
			for (int i = 0; i < sz; i++) {
				int x = q.front().first, y = q.front().second; q.pop();
				for (int k = 0; k < 4; k++) {
					int tx = x + d[k][0], ty = y + d[k][1];
					if (tx >= 0 && tx < n && ty >= 0 && ty < m && A[tx][ty] != -1) {
                        if (A[tx][ty] == 1) 
                            return op;
						q.push({tx, ty});
						A[tx][ty] = -1;
					}
				}
			}
			op++;
		}
		return op;
    }
};

复杂度分析

  • 时间复杂度: O ( n × m ) O(n × m) O(n×m)
  • 空间复杂度: O ( n × m ) O(n × m) O(n×m)

你可能感兴趣的:(●,搜索,bfs)