DFS

枫长...大约 5 分钟

200.岛屿数量open in new window

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

解题思路:图论中很经典的bfs问题,就是遍历所有的点,如果是1就碰到了一个岛屿,然后清空图上连着的所有1(如果不要求还原可以置0,如果要求还原可以置-1,最后再遍历一遍把-1置1即可)。最后返回你碰到1的个数即可。清空所有连着的点就是bfs,几乎就是bfs的模板,建议背过。时间复杂度,因为一个点最多遍历2次,所以是O(n^2)。

    vector<vector<int>> turn{{0,1},{1,0},{-1,0},{0,-1}};
    int numIslands(vector<vector<char>>& grid) {
        int m = grid.size();
        int n = grid[0].size();
        int ans = 0;
        deque<pair<int,int>> s;
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++){
                if(grid[i][j] == '1'){
                    ans++;
                    grid[i][j] = '0';
                    s.push_back({i, j});
                    while(!s.empty()) {
                        pair<int,int> x = s.front();
                        s.pop_front();
                        for(int k = 0; k < 4; k++){
                            int newi= x.first + turn[k][0];
                            int newj= x.second + turn[k][1];
                            if(newi >= 0 && newi < m && newj >= 0 && newj < n && grid[newi][newj] == '1'){
                                grid[newi][newj] = '0';
                                s.push_back({newi, newj});
                            }
                        }
                    }
                }
            }
        }
        return ans;
    }

22.括号生成open in new window

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

解题思路:

  • dfs,每层dfs可以添左括号,可以添右括号,每次递归带个变量记录左括号的个数,以及一个中间存储的字符串;
  • 添右括号条件是左括号数量大于0,递归结束的条件是生成括号的字符串已经达到2*n,且此时左括号个数为0。
class Solution {
public:
    vector<string> ans;
    void dfs(int n, int numC, string& tmp) {
        if(tmp.size() == 2*n) {
            if(numC == 0) {
                ans.emplace_back(tmp);
            }
            return;
        }
        tmp.push_back('(');
        dfs(n, numC + 1, tmp);
        tmp.pop_back();

        if(numC > 0) {
            tmp.push_back(')');
            dfs(n, numC - 1, tmp);
            tmp.pop_back();
        }
    }
    vector<string> generateParenthesis(int n) {
        string tmp = "";
        dfs(n, 0, tmp);
        return ans;
    }
};

695.岛屿的最大面积open in new window

给你一个大小为 m x n 的二进制矩阵 grid 。

岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。

岛屿的面积是岛上值为 1 的单元格的数目。

计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。

解题思路

  • 岛屿问题的变形,岛问题时候我们在dfs的时候没有记录每个岛中的1数量
  • 这道题只需要在岛问题的基础上记录一下每个岛中1的数量即可,让dfs返回dfs遍历过的1的个数。
  • 然后比较每个岛的1的数量找最大值即可。
class Solution {
public:
    vector<vector<int>> turn = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    int dfs(vector<vector<int>>& grid,int x,int y){
        grid[x][y] = 0;
        int n = grid.size();
        int m = grid[0].size();
        int res = 1;
        for(int i = 0; i < 4; i++){
            int nx = x + turn[i][0];
            int ny = y + turn[i][1];
            if(nx >= 0 && nx < n && ny >= 0 && ny < m && grid[nx][ny] == 1){
                res += dfs(grid, nx, ny);
            }
        }
        return res;
    }
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int n=grid.size();
        int m=grid[0].size();
        int ans=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(grid[i][j]){
                    ans=max(ans,dfs(grid,i,j));
                }
            }
        }
        return ans;
    }
};
你认为这篇文章怎么样?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.14.8