LeetCode - 934. Shortest Bridge (C++)

In a given 2D binary array A, there are two islands.  (An island is a 4-directionally connected group of 1s not connected to any other 1s.)

Now, we may change 0s to 1s so as to connect the two islands together to form 1 island.

Return the smallest number of 0s that must be flipped.  (It is guaranteed that the answer is at least 1.)

Example 1:

Input: [ [0,1],
         [1,0] ]
Output: 1

Example 2:

Input: [ [0,1,0],
         [0,0,0],
         [0,0,1] ]
Output: 2

解:

    一开始的想法是用DFS将两个岛找出来,将一个岛的点从1变成2,另一个岛的点从1变成3。然后遍历所有值为2的点,进行BFS,计算从第一个岛到第二个岛的所有路径中最短的一条。如下图所示:

    代码如下:

void bfs(vector<vector<int>> B, const int & N, int i, int j, const int& island, int curBridge, int& minBridge)
{
    if (B[i][j] == -1) return;              // 遍历过了
    if (B[i][j] != 0 && B[i][j] != island)  // 一定是另一个岛屿的点
    {
        minBridge = min(curBridge - 1, minBridge);
        return;
    }
    B[i][j] = -1;
    // 如果是同一片岛屿的点,直接跳过,因为肯定不会是最短路径
    if (i != N - 1 && B[i + 1][j] != island) bfs(B, N, i + 1, j, island, curBridge + 1, minBridge);
    if (i != 0 && B[i - 1][j] != island)     bfs(B, N, i - 1, j, island, curBridge + 1, minBridge);
    if (j != N - 1 && B[i][j + 1] != island) bfs(B, N, i, j + 1, island, curBridge + 1, minBridge);
    if (j != 0 && B[i][j - 1] != island)     bfs(B, N, i, j - 1, island, curBridge + 1, minBridge);
}

void dfs(vector<vector<int>>& A, int N, int i, int j, const int& island)
{
    A[i][j] = island;
    if (i != N - 1 && A[i + 1][j] == 1) dfs(A, N, i + 1, j, island);
    if (i != 0 && A[i - 1][j] == 1)     dfs(A, N, i - 1, j, island);
    if (j != N - 1 && A[i][j + 1] == 1) dfs(A, N, i, j + 1, island);
    if (j != 0 && A[i][j - 1] == 1)     dfs(A, N, i, j - 1, island);
}

int shortestBridge(vector<vector<int>>& A) {
    int N = A.size(), flag = 0;
    for (int i = 0; i < N && flag == 0; i++)    // 将第一个岛全标记为2
        for (int j = 0; j < N; j++)
            if (A[i][j] == 1)
            {
                dfs(A, N, i, j, 2);
                flag = 1;
                break;
            }
    for (int i = 0; i < N && flag == 0; i++)    // 将第二个岛全标记为3
        for (int j = 0; j < N; j++)
            if (A[i][j] == 1)
            {
                dfs(A, N, i, j, 3);
                flag = 1;
                break;
            }
    int minBridge = INT_MAX;
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            if (A[i][j] == 2)
            {
                bfs(A, N, i, j, 2, 0, minBridge);
                if(minBridge == 1) return 1;     // at least 1
            }
    return minBridge;
}

    和预期的一样,超时了。不过仔细一想,其实计算最短bridge不需要BFS的,只需要将两个岛的点存在两个vector里,然后计算这两个vector里每个元素的距离,最小的就是最短bridge。AC代码如下:

void dfs(vector<vector<int>>& A, int N, int i, int j, const int& island, vector<pair<int, int>>& vec)
{
    A[i][j] = island;
    vec.push_back(pair<int, int>(i, j));
    if (i != N - 1 && A[i + 1][j] == 1) dfs(A, N, i + 1, j, island, vec);
    if (i != 0 && A[i - 1][j] == 1)     dfs(A, N, i - 1, j, island, vec);
    if (j != N - 1 && A[i][j + 1] == 1) dfs(A, N, i, j + 1, island, vec);
    if (j != 0 && A[i][j - 1] == 1)     dfs(A, N, i, j - 1, island, vec);
}

int shortestBridge(vector<vector<int>>& A) {
    int N = A.size();
    bool flag = false;
    vector<pair<int, int>> a2p, a3p;	              // 两个岛所有点的坐标
    for (int i = 0; i < N && flag == false; i++) {    // 将第一个岛全标记为2
        for (int j = 0; j < N; j++)
            if (A[i][j] == 1)
            {
                dfs(A, N, i, j, 2, a2p);
                flag = true;
                break;
            }
    flag = false;
    for (int i = 0; i < N && flag == false; i++) {    // 将第二个岛全标记为3
        for (int j = 0; j < N; j++)
            if (A[i][j] == 1)
            {
                dfs(A, N, i, j, 3, a3p);
                flag = true;
                break;
            }
    int minBridge = INT_MAX;
    for (auto a2 : a2p)
        for (auto a3 : a3p)
            minBridge = min(abs(a2.first - a3.first) + abs(a2.second - a3.second) - 1, minBridge);
    return minBridge;
}

猜你喜欢

转载自blog.csdn.net/Bob__yuan/article/details/83960217