代码随想录Day41-图论:力扣第797m、200m、695m、1020m、130m题

这篇具有很好参考价值的文章主要介绍了代码随想录Day41-图论:力扣第797m、200m、695m、1020m、130m题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

797m. 所有可能的路径

题目链接
代码随想录文章讲解链接

方法一:DFS

用时:11m43s

思路
  • 时间复杂度: O ( n ⋅ 2 n ) O(n \cdot 2^n) O(n2n),n是节点个数,最坏情况每个节点都可以去往任意一个在它后面的节点,那么第i个节点去到最后一个节点的路径数就有 2 n − i − 2 2^{n-i-2} 2ni2,就是当前节点和最后一个节点必走,其他的节点有两种选择——走或不走。
  • 空间复杂度: O ( n ) O(n) O(n)
C++代码
class Solution {
private:
    vector<vector<int>> res;
    vector<int> path;

    void backTracking(vector<vector<int>>& graph, int i) {
        if (i == graph.size() - 1) {
            res.push_back(path);
            return;
        }
        for (int j = 0; j < graph[i].size(); ++j) {
            path.push_back(graph[i][j]);
            backTracking(graph, graph[i][j]);
            path.pop_back();  // 回溯
        }
    }

public:
    vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
        path.push_back(0);
        backTracking(graph, 0);
        return res;
    }
};

方法二:BFS

用时:16m18s

思路

队列中记录的元素是路径。

  • 时间复杂度: O ( ) O() O()
  • 空间复杂度: O ( ) O() O()
C++代码
class Solution {
public:
    vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
        queue<vector<int>> que;
        vector<vector<int>> res;

        que.push({0});
        while (!que.empty()) {
            vector<int> path = que.front();
            que.pop();
            for (int i = 0; i < graph[path.back()].size(); ++i) {
                vector<int> tmp = path;
                tmp.push_back(graph[path.back()][i]);
                if (tmp.back() == graph.size() - 1) res.push_back(tmp);
                else que.push(tmp);
            }
        }
        return res;
    }
};

看完讲解的思考

无。

代码实现遇到的问题

无。


200m. 岛屿数量

题目链接
代码随想录文章讲解链接

方法一:DFS

用时:17m48s

思路

遍历每个元素,若是陆地则使用DFS搜索与之相邻的所有陆地,并使用一个二维数组记录哪些陆地已经遍历过。
当遍历到新的岛屿时,岛屿数加1。

  • 时间复杂度: O ( m ⋅ n ) O(m \cdot n) O(mn)
  • 空间复杂度: O ( m ⋅ n ) O(m \cdot n) O(mn)
C++代码
class Solution {
private:
    int m;
    int n;
    int dir[4][2] = {0, -1, 1, 0, 0, 1, -1, 0};

    void dfs(vector<vector<char>>& grid, vector<vector<bool>>& visited, int x, int y) {
        visited[x][y] = true;
        for (int i = 0; i < 4; ++i) {
            int nextx = x + dir[i][0];
            int nexty = y + dir[i][1];
            if (!(nextx < 0 || nextx >= m || nexty < 0 || nexty >= n) && !visited[nextx][nexty] && grid[nextx][nexty] == '1') dfs(grid, visited, nextx, nexty);
        }
    }
    
public:
    int numIslands(vector<vector<char>>& grid) {
        m = grid.size();
        n = grid[0].size();
        vector<vector<bool>> visited(m, vector<bool>(n, false));
        int res = 0;

        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (!visited[i][j] && grid[i][j] == '1') {
                    ++res;
                    dfs(grid, visited, i, j);
                }
            }
        }
        return res;
    }
};

方法二:方法一优化

思路

可以不用数组记录哪些陆地访问过,只用把访问过的陆地置0即可。

  • 时间复杂度: O ( m ⋅ n ) O(m \cdot n) O(mn)
  • 空间复杂度: O ( m ⋅ n ) O(m \cdot n) O(mn)
C++代码
class Solution {
private:
    int m;
    int n;
    int dir[4][2] = {0, -1, 1, 0, 0, 1, -1, 0};

    void dfs(vector<vector<char>>& grid, int x, int y) {
        grid[x][y] = '0';
        for (int i = 0; i < 4; ++i) {
            int nextx = x + dir[i][0];
            int nexty = y + dir[i][1];
            if (!(nextx < 0 || nextx >= m || nexty < 0 || nexty >= n) && grid[nextx][nexty] == '1') dfs(grid, nextx, nexty);
        }
    }

public:
    int numIslands(vector<vector<char>>& grid) {
        m = grid.size();
        n = grid[0].size();
        int res = 0;

        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == '1') {
                    ++res;
                    dfs(grid, i, j);
                }
            }
        }
        return res;
    }
};

看完讲解的思考

代码实现遇到的问题

方法三:BFS

思路
  • 时间复杂度: O ( m ⋅ n ) O(m \cdot n) O(mn)
  • 空间复杂度: O ( m i n ( m , n ) ) O(min(m,n)) O(min(m,n))
C++代码
class Solution {
private:
    int m;
    int n;
    int dir[4][2] = {0, -1, 1, 0, 0, 1, -1, 0};

    void bfs(vector<vector<char>>& grid, int x, int y) {
        queue<pair<int, int>> que;
        grid[x][y] = '0';
        que.push(pair<int, int>(x, y));
        while (!que.empty()) {
            pair<int, int> tmp = que.front();
            que.pop();
            for (int i = 0; i < 4; ++i) {
                int nextx = tmp.first + dir[i][0];
                int nexty = tmp.second + dir[i][1];
                if (!(nextx < 0 || nextx >= m || nexty < 0 || nexty >= n) && grid[nextx][nexty] == '1') {
                    grid[nextx][nexty] = '0';
                    que.push(pair<int, int>(nextx, nexty));
                }
            }
        }
    }

public:
    int numIslands(vector<vector<char>>& grid) {
        m = grid.size();
        n = grid[0].size();
        int res = 0;

        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == '1') {
                    ++res;
                    bfs(grid, i, j);
                }
            }
        }
        return res;
    }
};

看完讲解的思考

无。

代码实现遇到的问题

无。


695m. 岛屿的最大面积

题目链接
代码随想录文章讲解链接

方法一:DFS

用时:16m39s

思路

当遇到陆地时,DFS该岛屿,记录该岛屿的面积,并将遍历过的陆地置零,最后返回最大的岛屿的面积。

  • 时间复杂度: O ( m ⋅ n ) O(m \cdot n) O(mn)
  • 空间复杂度: O ( m ⋅ n ) O(m \cdot n) O(mn)
C++代码
class Solution {
private:
    int m;
    int n;
    int area;

    void dfs(vector<vector<int>>& grid, int x, int y) {
        grid[x][y] = 0;
        area += 1;
        if (x - 1 >= 0 && grid[x - 1][y] == 1) dfs(grid, x - 1, y);
        if (x + 1 < m && grid[x + 1][y] == 1) dfs(grid, x + 1, y);
        if (y - 1 >= 0 && grid[x][y - 1] == 1) dfs(grid, x, y - 1);
        if (y + 1 < n && grid[x][y + 1] == 1) dfs(grid, x, y + 1);
    }

public:
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int res = 0;
        m = grid.size();
        n = grid[0].size();
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 1) {
                    area = 0;
                    dfs(grid, i, j);
                    res = max(res, area);
                }
            }
        }
        return res;
    }
};

方法二:BFS

思路
  • 时间复杂度: O ( m ⋅ n ) O(m \cdot n) O(mn)
  • 空间复杂度: O ( m i n ( m , n ) ) O(min(m,n)) O(min(m,n))
C++代码
class Solution {
private:
    int m;
    int n;
    int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};

    int bfs(vector<vector<int>>& grid, int x, int y) {
        int area = 1;
        queue<pair<int, int>> que;

        que.push(pair<int, int>(x, y));
        grid[x][y] = 0;
        while (!que.empty()) {
            pair<int, int> tmp = que.front();
            que.pop();
            for (int i = 0; i < 4; ++i) {
                int nextx = tmp.first + dir[i][0];
                int nexty = tmp.second + dir[i][1];
                if (!(nextx < 0 || nextx >= m || nexty < 0 || nexty >= n) && grid[nextx][nexty] == 1) {
                    grid[nextx][nexty] = 0;
                    area += 1;
                    que.push(pair<int, int>(nextx, nexty));
                }
            }
        }
        return area;
    }

public:
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int res = 0;
        m = grid.size();
        n = grid[0].size();
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 1) res = max(res, bfs(grid, i, j));
            }
        }
        return res;
    }
};

看完讲解的思考

无。

代码实现遇到的问题

BFS时,元素入列的时候就要做标记,不能在元素出列的时候才做标记,不然会重复遍历。


1020m. 飞地的数量

题目链接
代码随想录文章讲解链接

方法一:DFS

用时:20m42s

思路

在上一题695m的基础上,加多一个变量用于记录当前岛屿是否临界,如果不是的话将岛屿的陆地数量记录。

  • 时间复杂度: O ( m ⋅ n ) O(m \cdot n) O(mn)
  • 空间复杂度: O ( m ⋅ n ) O(m \cdot n) O(mn)
C++代码
class Solution {
private:
    int m;
    int n;
    int num;
    bool flag;

    void dfs(vector<vector<int>>& grid, int x, int y) {
        grid[x][y] = 0;
        num += 1;
        if (x - 1 < 0) flag = true;
        else if (grid[x - 1][y] == 1) dfs(grid, x - 1, y);
        if (x + 1 >= m) flag = true;
        else if (grid[x + 1][y] == 1) dfs(grid, x + 1, y);
        if (y - 1 < 0) flag = true;
        else if (grid[x][y - 1] == 1) dfs(grid, x, y - 1);
        if (y + 1 >= n) flag = true;
        else if (grid[x][y + 1] == 1) dfs(grid, x, y + 1);
    }

public:
    int numEnclaves(vector<vector<int>>& grid) {
        int res = 0;
        m = grid.size();
        n = grid[0].size();
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 1) {
                    num = 0;
                    flag = false;
                    dfs(grid, i, j);
                    if (!flag) res += num;
                }
            }
        }
        return res;
    }
};

方法二:BFS

思路
  • 时间复杂度: O ( m ⋅ n ) O(m \cdot n) O(mn)
  • 空间复杂度: O ( m i n ( m , n ) ) O(min(m,n)) O(min(m,n))
C++代码
class Solution {
private:
    int m;
    int n;
    int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};

    int bfs(vector<vector<int>>& grid, int x, int y) {
        int num = 1;
        queue<pair<int, int>> que;

        que.push(pair<int, int>(x, y));
        grid[x][y] = 0;
        while (!que.empty()) {
            pair<int, int> tmp = que.front();
            que.pop();
            for (int i = 0; i < 4; ++i) {
                int nextx = tmp.first + dir[i][0];
                int nexty = tmp.second + dir[i][1];
                if (nextx < 0 || nextx >= m || nexty < 0 || nexty >= n) num = INT_MIN;
                else if (grid[nextx][nexty] == 1) {
                    grid[nextx][nexty] = 0;
                    ++num;
                    que.push(pair<int, int>(nextx, nexty));
                }
            }
        }
        return num;
    }

public:
    int numEnclaves(vector<vector<int>>& grid) {
        int res = 0;
        m = grid.size();
        n = grid[0].size();
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 1) res += max(0, bfs(grid, i, j));
            }
        }
        return res;
    }
};

看完讲解的思考

无。

代码实现遇到的问题

无。


130m. 被围绕的区域

题目链接
代码随想录文章讲解链接

方法一:DFS

用时:17m13s

思路

遍历位于临界的元素,若是’O’则将连通的’O’变成’H’,最后再将board中的所有’O’替换成’X’,‘H’替换成’O’,因为此时剩下的’O’是位于board内部的无法连接到外部的元素,直接将其变成’X’,而’H’是可以连通到外部的’O’,将其变回’O’。

  • 时间复杂度: O ( m ⋅ n ) O(m \cdot n) O(mn)
  • 空间复杂度: O ( m ⋅ n ) O(m \cdot n) O(mn)
C++代码
class Solution {
private:
    int m;
    int n;

    void dfs(vector<vector<char>>& board, int x, int y) {
        board[x][y] = 'H';
        if (x - 1 >= 0 && board[x - 1][y] == 'O') dfs(board, x - 1, y);
        if (x + 1 < m && board[x + 1][y] == 'O') dfs(board, x + 1, y);
        if (y - 1 >= 0 && board[x][y - 1] == 'O') dfs(board, x, y - 1);
        if (y + 1 < n && board[x][y + 1] == 'O') dfs(board, x, y + 1);
    }

public:
    void solve(vector<vector<char>>& board) {
        m = board.size();
        n = board[0].size();
        for (int i = 0; i < m; ++i) {
            if (board[i][0] == 'O') dfs(board, i, 0);
            if (board[i][n - 1] == 'O') dfs(board, i, n - 1);
        }
        for (int i = 0; i < n; ++i) {
            if (board[0][i] == 'O') dfs(board, 0, i);
            if (board[m - 1][i] == 'O') dfs(board, m - 1, i);
        }
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (board[i][j] == 'H') board[i][j] = 'O';
                else if (board[i][j] == 'O') board[i][j] = 'X';
            }
        }
    }
};

方法二:BFS

思路

就是遍历的方法从DFS换成BFS,懒得写了。

  • 时间复杂度: O ( m ⋅ n ) O(m \cdot n) O(mn)
  • 空间复杂度: O ( m i n ( m , n ) ) O(min(m,n)) O(min(m,n))

看完讲解的思考

无。

代码实现遇到的问题

无。


最后的碎碎念

就快要一刷完代码随想录,冲!文章来源地址https://www.toymoban.com/news/detail-738936.html

到了这里,关于代码随想录Day41-图论:力扣第797m、200m、695m、1020m、130m题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 代码随想录第41天 | 动态规划part03

    ● 343. 整数拆分 ● 96.不同的二叉搜索树 题目一 343. 整数拆分 给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。 示例 : 输入: 10 输出: 36 解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。 说明: 你可以假设 n 不小于 2 且不大于 5

    2024年01月24日
    浏览(33)
  • 代码随想录 图论

    目录 797.所有可能得路径  200.岛屿数量 695.岛屿的最大面积 1020.飞地的数量  130.被围绕的区域  417.太平洋大西洋水流问题  827.最大人工岛 127.单词接龙  841.钥匙和房间 463.岛屿的周长  797. 所有可能的路径 中等 给你一个有  n  个节点的  有向无环图(DAG) ,请你找出所有从

    2024年04月10日
    浏览(31)
  • 代码随想录(番外)图论1

    1. 深度优先搜索理论基础 2. 所有可能的路径 3. 广度优先搜索理论基础.md https://programmercarl.com/%E5%9B%BE%E8%AE%BA%E6%B7%B1%E6%90%9C%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 1. 深度优先搜索理论基础 总结 同理回溯算法,换汤不换药 二叉树递归讲解 (opens new window)中,给出了递归三部曲。 回溯算

    2024年04月28日
    浏览(27)
  • 代码随想录(番外)图论4

    417. 太平洋大西洋水流问题 那么我们可以 反过来想,从太平洋边上的节点 逆流而上,将遍历过的节点都标记上。 从大西洋的边上节点 逆流而长,将遍历过的节点也标记上。 然后两方都标记过的节点就是既可以流太平洋也可以流大西洋的节点。 也就是说通过从两边的大洋开

    2024年04月29日
    浏览(42)
  • 代码随想录day44

    完全背包 其实就是每个物品可以使用无数次,给我们一个容器,装满这个容器的最大价值是多少。 思路: 如果求组合数就是外层for循环遍历物品,内层for遍历背包。 如果求排列数就是外层for遍历背包,内层for循环遍历物品。 完全背包的组合和排序 518. 零钱兑换 II 题目 给你

    2023年04月17日
    浏览(36)
  • 代码随想录Day50

    昨天因为准备面试所以咕咕了一天。今天继续学习动规算法,尽管背包问题已经结束但其中的各类思想仍需要进一步理解。 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两

    2023年04月14日
    浏览(29)
  • 代码随想录day59

    647. 回文子串 给你一个字符串  s  ,请你统计并返回这个字符串中  回文子串  的数目。 回文字符串  是正着读和倒过来读一样的字符串。 子字符串  是字符串中的由连续字符组成的一个序列。 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不

    2024年02月07日
    浏览(25)
  • 代码随想录Day58

    昨天因为志愿活动和笔试耽误了一整天,今天继续学习动规解决子序列问题。 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,\\\"ace\\\"是\\\"abcde\\\"的一个子序列,

    2023年04月27日
    浏览(30)
  • 代码随想录day11

    20. 有效的括号   思路:这里用模拟栈的方法会更好理解,也就是我们每次遇到朝左方向的三种类型的时候,就加入相反方向的右括号到result栈中。由于栈是一个先进后出的方式,所以我们会有一个判断stack当前为不为空,和stack[-1]是不是和当前循环到的括号相同。如果说相同

    2024年02月13日
    浏览(25)
  • 代码随想录day02

    ● 力扣题目链接 ● 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 思路 ● 暴力排序,时间复杂度O(n + nlogn) ● 使用双指针,时间复杂度O(n) 代码 ● 力扣题目链接 ● 给定一个含有 n 个正整数的数组和一个正整

    2024年02月13日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包