【LeetCode 934】Shortest Bridge

题目描述:

给一个01矩阵,0表示水,1表示相连的岛。
一共有两个岛。
问最少填多少个0,能把两个岛连接起来。

思路:

先找到随机一个岛,并用bfs把这个岛的值和step值设置为-1和0。然后以这个岛上的任意一点开始bfs,找到1记录此时最小值,否则加入队列。找到1以后还是要继续搜索,最后返回最小值。

代码:

class Solution {
public:
    int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    
    int shortestBridge(vector<vector<int>>& A) {
        int n = A.size();
        int m = A[0].size();
        
        vector<vector<int> > step(n, vector<int>(m, INT_MAX));
        int stx, sty;
        
        bool init = false; 
        for (int i=0; i<n; ++i) {
            for (int j=0; j<m; ++j) {
                if (A[i][j] == 1) {
                    stx = i;
                    sty = j;
                    init_func(i, j, A, step);
                    init = true;
                    break;
                }
            }
            if (init) break;
        }
        
        int ans = bridge(stx, sty, A, step);
        return ans-1;
    }
    
    int bridge(int stx, int sty, vector<vector<int>>& A, vector<vector<int>>& step) {
        int n = A.size();
        int m = A[0].size();
        vector<vector<bool>> vis(n, vector<bool>(m, false));
        vis[stx][sty] = 1;
        queue<pair<int, int>> que;
        que.push(make_pair(stx, sty));
        int ans = INT_MAX;
        
        while(!que.empty()) {
            int curx = que.front().first;
            int cury = que.front().second;
            que.pop();
            
            for (int i=0; i<4; ++i) {
                int nxtx = curx + dir[i][0];
                int nxty = cury + dir[i][1];
                if (nxtx < 0 || nxtx >= n || nxty < 0 || nxty >= m) continue;
                
                if (A[nxtx][nxty] == -1 && !vis[nxtx][nxty]) {
                    que.push(make_pair(nxtx, nxty));
                    vis[nxtx][nxty] = 1;
                }
                if (A[nxtx][nxty] == 0 && step[nxtx][nxty] > step[curx][cury] + 1) {
                    step[nxtx][nxty] = step[curx][cury] + 1;
                    que.push(make_pair(nxtx, nxty));
                }
                if (A[nxtx][nxty] == 1) {
                    step[nxtx][nxty] = step[curx][cury] + 1;
                    ans = min(ans, step[nxtx][nxty]);
                }
            }
        }
        return ans;
    }
    
    
    void init_func(int x, int y, vector<vector<int>>& A, vector<vector<int>>& step) {
        int n = A.size();
        int m = A[0].size();
        queue<pair<int, int>> que;
        que.push(make_pair(x, y));
        step[x][y] = 0;
        A[x][y] = -1;
        
        while(!que.empty()) {
            int curx = que.front().first;
            int cury = que.front().second;
            que.pop();
            
            for (int i=0; i<4; ++i) {
                int nxtx = curx + dir[i][0];
                int nxty = cury + dir[i][1];
                if (nxtx < 0 || nxtx >= n || nxty < 0 || nxty >= m) continue;
                if (step[nxtx][nxty] && A[nxtx][nxty] == 1) {
                    step[nxtx][nxty] = 0;
                    A[nxtx][nxty] = -1;
                    que.push(make_pair(nxtx, nxty));
                } 
            }
        }
    }
};

这里的结束条件是队列为空。
bfs先找到的什么时候就值最值呢。
刚才看见英语同桌给同楼的妹子送水果。
他谈恋爱了。
是柠檬的味道。

猜你喜欢

转载自blog.csdn.net/iCode_girl/article/details/92794544