LeetCode/solutions/130. Surrounded Regions.md
2019-07-17 10:25:12 +08:00

2.2 KiB
Raw Blame History

130. Surrounded Regions

思路

有一个二维的只包含O和X的矩形区域题目要求将被X包住的O都变成X边缘的O不算被包围。
这题很容易想到的是遍历一遍矩形若遇到了O就从这个O出发进行DFS或者BFS看会不会遇到边界如果遇不到则说明是被包围的然后将这些O变成X。

但是上面的思路在矩形很大的时候亲测会超时,我们可以用反向思路考虑: 扫描矩阵的四条边如果有O则用DFS遍历将所有连着的O都变成另一个字符比如N这样剩下的O都是被包围的最后将这些O变成X把N变回O就行了。 由于这个思路是只从矩形的四条边进行DFS所以比最开始的思路复杂度要低很多虽然理论复杂度都是O(m*n), m和n分别是矩形的高和宽

C++

class Solution {
private:
    vector<int>dx{1, -1, 0, 0};
    vector<int>dy{0, 0, 1, -1};
    int m, n;
    void DFS(vector<vector<char>>& board, int i, int j){
        if(i < 0 || j < 0 || i > m-1 || j > n-1) return; // 超出矩形区域
        if(board[i][j] == 'X' || board[i][j] == 'N') return;
        
        // board[i][j] == 'O'
        board[i][j] = 'N';
        int next_i, next_j;
        for(int k = 0; k < 4; k++) {
            next_i = i+dx[k];
            next_j = j+dy[k];
            // 提前判断一下会快不少
            if(next_i < 0 || next_j < 0 || next_i > m-1 || next_j > n-1) continue;
            DFS(board, next_i, next_j);
        }      
    }
public:
    void solve(vector<vector<char>>& board) {
        m = board.size();
        if(m == 0) return;
        n = board[0].size();
        
        for(int j = 0; j < n; j++){
            DFS(board, 0, j);
            DFS(board, m-1, j);
        }
        
        for(int i = 1; i < m-1; i++){
            DFS(board, i, 0);
            DFS(board, i, n-1);
        }
                          
        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++){
                if(board[i][j] == 'N') board[i][j] = 'O';
                else if(board[i][j] == 'O') board[i][j] = 'X';
            }
    }
};