[LeetCode] 130. Surrounded Regions 包圍區域

 1.DFS  c++

       這道題讓將矩陣中被'X'包圍的不接觸邊框的'O組成的連通份量用'X'替換,顯然能夠使用DFS的方法解答,直接的想法是,遍歷二維矩陣,遇到‘O’使用DFS判斷由'O'組成的連通份量有沒有接觸到邊框,數組

沒有接觸到DFS返回true,並將'O組成的連通份量用'X'替換;不然返回false,不替換。在使用DFS遍歷'O'連通份量的過程當中使用數組保存遍歷路徑。此種方法容易出錯。代碼以下:app

/*
 * @Descripttion: 
 * @version: 
 * @Author: wangxf
 * @Date: 2020-04-14 20:38:54
 * @LastEditors: Do not edit
 * @LastEditTime: 2020-04-20 23:19:05
 */
/*
 * @lc app=leetcode.cn id=130 lang=cpp
 *
 * [130] 被圍繞的區域
 */

// @lc code=start
#include<bits/stdc++.h>
using namespace std;
class Solution {
public:
    void solve(vector<vector<char>>& board) {
         if(board.empty()||board.size()<1) return;
         vector<vector<char>> flag =  board;
         raw_len = board.size();
         col_len = board[0].size();
         for(int i = 0;i<raw_len;++i)
            for(int j = 0;j<col_len;++j)
            {
                flag[i][j]='N';//未訪問
            }
         for(int i = 0;i<raw_len;++i)
            for(int j = 0;j<col_len;++j)
            {
                if(board[i][j]=='O'){
                    vector<pair<int,int> > pathVec;
                    pathVec.clear();
                    bool isModify = dfs(board,flag,pathVec,i,j);
                    if(isModify)
                    {
                        vector<pair<int,int> >::iterator ite = pathVec.begin();
                        for(;ite!=pathVec.end();++ite){
                            int x = ite->first;
                            int y = ite->second;
                            board[x][y]='X';
                        }
                    }
                }
            }
        return;
    }
    bool dfs(vector<vector<char> >& board,vector<vector<char> >& flag,
             vector<pair<int,int> >& pathVec,int i,int j)
    {
         if(!(i>=0&&i<raw_len&&j>=0&&j<col_len)){//放在函數最開始,避免數組下標越界
             return false;
         } 
         bool status = true;
         if(board[i][j]=='O'&&flag[i][j]=='N'){//沒有被訪問過的‘O’節點
            flag[i][j]='Y';//標記訪問
            pair<int,int> point = make_pair(i,j);
            pathVec.push_back(point);//記錄一次dfs過程當中的路徑
            if(i==0||j==0){//遇到邊界,不填充
                status=false;
            }
            int dx[4]={0,0,-1,1};
            int dy[4]={1,-1,0,0};
            for(int k=0;k<4;++k){
                status=(status&dfs(board,flag,pathVec,i+dx[k],j+dy[k]));
            }
            return status;
         }
        return status; 
    }
private:
    int raw_len;
    int col_len;
};
// @lc code=end

     另外一種比較巧妙一點的DFS方法是掃矩陣的四條邊,若是有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);
        }
    }
};

2.並查集spa

相關文章
相關標籤/搜索