最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++實(shí)現(xiàn)LeetCode(130.包圍區(qū)域)

 更新時(shí)間:2021年07月27日 15:53:01   作者:Grandyang  
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(130.包圍區(qū)域),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下

[LeetCode] 130. Surrounded Regions 包圍區(qū)域

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.

這是道關(guān)于 XXOO 的題,有點(diǎn)像圍棋,將包住的O都變成X,但不同的是邊緣的O不算被包圍,跟之前那道 Number of Islands 很類似,都可以用 DFS 來解。剛開始我的思路是 DFS 遍歷中間的O,如果沒有到達(dá)邊緣,都變成X,如果到達(dá)了邊緣,將之前變成X的再變回來。但是這樣做非常的不方便,在網(wǎng)上看到大家普遍的做法是掃矩陣的四條邊,如果有O,則用 DFS 遍歷,將所有連著的O都變成另一個(gè)字符,比如 \$,這樣剩下的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);
        }
    }
};

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

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

解法二:

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后,然后利用隊(duì)列 queue 進(jìn)行 BFS 查找和其相連的所有O,然后都標(biāo)記上美元號(hào)。最后的處理還是先把所有的O變成X,然后再把美元號(hào)變回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';
            }
        }
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/130

類似題目:

Number of Islands

Walls and Gates

參考資料:

https://leetcode.com/problems/surrounded-regions/

https://leetcode.com/problems/surrounded-regions/discuss/41895/Share-my-clean-Java-Code

https://leetcode.com/problems/surrounded-regions/discuss/41825/Simple-BFS-solution-easy-to-understand

https://leetcode.com/problems/surrounded-regions/discuss/41612/A-really-simple-and-readable-C%2B%2B-solutionuff0conly-cost-12ms

到此這篇關(guān)于C++實(shí)現(xiàn)LeetCode(130.包圍區(qū)域)的文章就介紹到這了,更多相關(guān)C++實(shí)現(xiàn)包圍區(qū)域內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 遞歸法求最大公約數(shù)和最小公倍數(shù)的實(shí)現(xiàn)代碼

    遞歸法求最大公約數(shù)和最小公倍數(shù)的實(shí)現(xiàn)代碼

    今天整理了一下用遞歸法求最大公約數(shù)(gcd)和最小公倍數(shù)(lcm)。主要的工作是求最大公約數(shù)。數(shù)學(xué)上可以用輾轉(zhuǎn)法求最大公約數(shù)
    2013-05-05
  • Qt QCompleter自動(dòng)補(bǔ)全的實(shí)現(xiàn)

    Qt QCompleter自動(dòng)補(bǔ)全的實(shí)現(xiàn)

    本文主要介紹了Qt QCompleter自動(dòng)補(bǔ)全的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • C語言實(shí)現(xiàn)牛頓迭代法解方程詳解

    C語言實(shí)現(xiàn)牛頓迭代法解方程詳解

    這篇文章主要介紹了C語言實(shí)現(xiàn)牛頓迭代法解方程詳解的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Qt中布局管理的使用小結(jié)

    Qt中布局管理的使用小結(jié)

    Qt的布局管理系統(tǒng)提供了簡(jiǎn)單而強(qiáng)大的機(jī)制,確保它們有效地使用空間,本文就介紹了Qt中布局管理的使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • 一文詳解C++的訪問說明符

    一文詳解C++的訪問說明符

    訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關(guān)鍵字,它們用于封裝類數(shù)據(jù)并保護(hù)其免受意外修改或?yàn)E用,本文將給大家詳細(xì)的介紹一下C++的訪問說明符,感興趣的朋友可以參考下
    2024-04-04
  • 在C++程序中開啟和禁用Windows設(shè)備的無線網(wǎng)卡的方法

    在C++程序中開啟和禁用Windows設(shè)備的無線網(wǎng)卡的方法

    這篇文章主要介紹了在C++程序中開啟和禁用Windows設(shè)備的無線網(wǎng)卡的方法,包括一些常見錯(cuò)誤的分析與解決,需要的朋友可以參考下
    2016-03-03
  • C語言之浮點(diǎn)數(shù)的表示與儲(chǔ)存方式

    C語言之浮點(diǎn)數(shù)的表示與儲(chǔ)存方式

    這篇文章主要介紹了C語言之浮點(diǎn)數(shù)的表示與儲(chǔ)存方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • C/C++練習(xí)題之合并k個(gè)已排序的鏈表

    C/C++練習(xí)題之合并k個(gè)已排序的鏈表

    這篇文章主要給大家介紹了關(guān)于C/C++練習(xí)題之合并k個(gè)已排序的鏈表的相關(guān)資料,文中通過圖文以及實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C/C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-06-06
  • C語言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法

    C語言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法

    這篇文章主要介紹了C語言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法,涉及C語言針對(duì)數(shù)組的遍歷與判斷技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • QT進(jìn)行CSV文件初始化與讀寫操作

    QT進(jìn)行CSV文件初始化與讀寫操作

    這篇文章主要為大家詳細(xì)介紹了在QT環(huán)境中如何進(jìn)行CSV文件的初始化、寫入和讀取操作,本文為大家整理了相關(guān)的操作的多種方法,希望對(duì)大家有所幫助
    2025-04-04

最新評(píng)論

茶陵县| 靖远县| 白沙| 临颍县| 石楼县| 垫江县| 炉霍县| 民乐县| 方正县| 南郑县| 商洛市| 湟源县| 南雄市| 九寨沟县| 太康县| 鸡西市| 响水县| 兴宁市| 荥阳市| 合肥市| 甘孜县| 大厂| 独山县| 盖州市| 白玉县| 临汾市| 墨玉县| 武城县| 锡林浩特市| 微山县| 塔河县| 梓潼县| 开封县| 巫山县| 望奎县| 张家口市| 邵阳县| 辽中县| 应城市| 丰原市| 安龙县|