亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++實現LeetCode之包圍區域的示例分析

發布時間:2021-07-28 09:04:26 來源:億速云 閱讀:188 作者:小新 欄目:開發技術

這篇文章將為大家詳細講解有關C++實現LeetCode之包圍區域的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

[LeetCode] 130. Surrounded Regions 包圍區域

Given a 2D board containing 'X' and 'O'(the letter O), capture all regions surrounded by 'X'.

A region is captured by flipping all 'O's into 'X's in that surrounded region.

Example:

X X X X
X O O X
X X O X
X O X X

After running your function, the board should be:

X X X X
X X X X
X X X X
X O X X

Explanation:

Surrounded regions shouldn't be on the border, which means that any 'O' on the border of the board are not flipped to 'X'. Any 'O' that is not on the border and it is not connected to an 'O' on the border will be flipped to 'X'. Two cells are connected if they are adjacent cells connected horizontally or vertically.

這是道關于 XXOO 的題,有點像圍棋,將包住的O都變成X,但不同的是邊緣的O不算被包圍,跟之前那道 Number of Islands 很類似,都可以用 DFS 來解。剛開始我的思路是 DFS 遍歷中間的O,如果沒有到達邊緣,都變成X,如果到達了邊緣,將之前變成X的再變回來。但是這樣做非常的不方便,在網上看到大家普遍的做法是掃矩陣的四條邊,如果有O,則用 DFS 遍歷,將所有連著的O都變成另一個字符,比如 \$,這樣剩下的O都是被包圍的,然后將這些O變成X,把$變回O就行了。代碼如下:

解法一:

class Solution {
public:
    void solve(vector<vector<char> >& board) {
        for (int i = 0; i < board.size(); ++i) {
            for (int j = 0; j < board[i].size(); ++j) {
                if ((i == 0 || i == board.size() - 1 || j == 0 || j == board[i].size() - 1) && board[i][j] == 'O')
                    solveDFS(board, i, j);
            }
        }
        for (int i = 0; i < board.size(); ++i) {
            for (int j = 0; j < board[i].size(); ++j) {
                if (board[i][j] == 'O') board[i][j] = 'X';
                if (board[i][j] == '$') board[i][j] = 'O';
            }
        }
    }
    void solveDFS(vector<vector<char> > &board, int i, int j) {
        if (board[i][j] == 'O') {
            board[i][j] = '$';
            if (i > 0 && board[i - 1][j] == 'O') 
                solveDFS(board, i - 1, j);
            if (j < board[i].size() - 1 && board[i][j + 1] == 'O') 
                solveDFS(board, i, j + 1);
            if (i < board.size() - 1 && board[i + 1][j] == 'O') 
                solveDFS(board, i + 1, j);
            if (j > 0 && board[i][j - 1] == 'O') 
                solveDFS(board, i, j - 1);
        }
    }
};

很久以前,上面的代碼中最后一個 if 中必須是 j > 1 而不是 j > 0,為啥 j > 0 無法通過 OJ 的最后一個大數據集合,博主開始也不知道其中奧秘,直到被另一個網友提醒在本地機子上可以通過最后一個大數據集合,于是博主也寫了一個程序來驗證,請參見驗證 LeetCode Surrounded Regions 包圍區域的DFS方法,發現 j > 0 是正確的,可以得到相同的結果。神奇的是,現在用 j > 0  也可以通過 OJ 了。

下面這種解法還是 DFS 解法,只是遞歸函數的寫法稍有不同,但是本質上并沒有太大的區別,參見代碼如下:

解法二:

class Solution {
public:
    void solve(vector<vector<char>>& board) {
        if (board.empty() || board[0].empty()) return;
        int m = board.size(), n = board[0].size();
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (i == 0 || i == m - 1 || j == 0 || j == n - 1) {
                    if (board[i][j] == 'O') dfs(board, i , j);
                }
            }   
        }
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (board[i][j] == 'O') board[i][j] = 'X';
                if (board[i][j] == '$') board[i][j] = 'O';
            }
        }
    }
    void dfs(vector<vector<char>> &board, int x, int y) {
        int m = board.size(), n = board[0].size();
        vector<vector<int>> dir{{0,-1},{-1,0},{0,1},{1,0}};
        board[x][y] = '$';
        for (int i = 0; i < dir.size(); ++i) {
            int dx = x + dir[i][0], dy = y + dir[i][1];
            if (dx >= 0 && dx < m && dy > 0 && dy < n && board[dx][dy] == 'O') {
                dfs(board, dx, dy);
            }
        }
    }
};

我們也可以使用迭代的解法,但是整體的思路還是一樣的,在找到邊界上的O后,然后利用隊列 queue 進行 BFS 查找和其相連的所有O,然后都標記上美元號。最后的處理還是先把所有的O變成X,然后再把美元號變回O即可,參見代碼如下:

解法三:

class Solution {
public:
    void solve(vector<vector<char>>& board) {
        if (board.empty() || board[0].empty()) return;
        int m = board.size(), n = board[0].size();
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (i != 0 && i != m - 1 && j != 0 && j != n - 1) continue;
                if (board[i][j] != 'O') continue;
                board[i][j] = '$';
                queue<int> q{{i * n + j}};
                while (!q.empty()) {
                    int t = q.front(), x = t / n, y = t % n; q.pop();
                    if (x >= 1 && board[x - 1][y] == 'O') {board[x - 1][y] = '$'; q.push(t - n);}
                    if (x < m - 1 && board[x + 1][y] == 'O') {board[x + 1][y] = '$'; q.push(t + n);}
                    if (y >= 1 && board[x][y - 1] == 'O') {board[x][y - 1] = '$'; q.push(t - 1);}
                    if (y < n - 1 && board[x][y + 1] == 'O') {board[x][y + 1] = '$'; q.push(t + 1);}
                }
            }
        }
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (board[i][j] == 'O') board[i][j] = 'X';
                if (board[i][j] == '$') board[i][j] = 'O';
            }
        }
    }
};

關于“C++實現LeetCode之包圍區域的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

色达县| 尉犁县| 和田县| 阳谷县| 孟州市| 石狮市| 左云县| 东乡族自治县| 金沙县| 天全县| 云和县| 忻州市| 澄城县| 浠水县| 策勒县| 龙游县| 丹巴县| 托克逊县| 治多县| 扶沟县| 阿克陶县| 云南省| 沙河市| 张家口市| 兰溪市| 巴塘县| 阳新县| 北海市| 龙门县| 天全县| 金门县| 图们市| 鄄城县| 常州市| 甘德县| 巴中市| 磐安县| 金塔县| 灵宝市| 新竹县| 阳新县|