从小白开始刷算法 dfs篇 leetcode.200

简介: 从小白开始刷算法 dfs篇 leetcode.200

序言

虽然算法很难,但不应该就放弃。这是一个学习笔记,希望你们喜欢~

先自己尝试写,大概十几分钟仍然写不出来

看思路,再尝试跟着思路写

仍然写不出来,再看视频

b站up视频推荐:爱学习的饲养员

leetcode其他文章:

数组篇:

从小白开始刷算法 数组篇 leetcode.485

从小白开始刷算法 数组篇 leetcode.283

从小白开始刷算法 数组篇 leetcode.27

链表篇:

从小白开始刷算法 ListNode 链表篇 leetcode.203

从小白开始刷算法 ListNode 链表篇 leetcode.206

队列篇

从小白开始刷算法 ListNode 链表篇 leetcode.933

栈篇

从小白开始刷算法 Stack 栈篇 leetcode.20

从小白开始刷算法 Stack 栈篇 leetcode.496

哈希篇

从小白开始刷算法 Hash 哈希篇 leetcode.217

从小白开始刷算法 Hash 哈希篇 leetcode.705

树篇

从小白开始刷算法 Tree 树篇 先序遍历 leetcode.144

从小白开始刷算法 Tree 树篇 中序遍历 leetcode.94

从小白开始刷算法 Tree 树篇 后序遍历 leetcode.94

堆篇

从小白开始刷算法 Heap 堆篇 最大堆排序 leetcode.215

小白开始刷算法 Heap 堆篇 最小堆排序 leetcode.692

双指针篇

从小白开始刷算法 对撞双指针 leetcode.881

从小白开始刷算法 快慢双指针篇 leetcode.141

二分法篇

从小白开始刷算法 二分法篇 leetcode.704

从小白开始刷算法 二分法篇 leetcode.35

从小白开始刷算法 二分法篇 leetcode.162

从小白开始刷算法 二分法篇 leetcode.74

滑动窗口篇

从小白开始刷算法 滑动窗口篇 leetcode.209

从小白开始刷算法 滑动窗口篇 leetcode.1456

递归篇

从小白开始刷算法 递归篇 leetcode.509

从小白开始刷算法 递归篇 leetcode.206

分治法篇

从小白开始刷算法 分治法篇 leetcode.169

从小白开始刷算法 分治法篇 leetcode.53

回溯法篇

从小白开始刷算法 回溯法篇 leetcode.22

从小白开始刷算法 回溯法篇 leetcode.78

dfs篇

从小白开始刷算法 dfs篇 leetcode.938

dfs篇

难度:中等

题目:

200. 岛屿数量

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

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

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

示例 1:

输入:grid = [

[“1”,“1”,“1”,“1”,“0”],

[“1”,“1”,“0”,“1”,“0”],

[“1”,“1”,“0”,“0”,“0”],

[“0”,“0”,“0”,“0”,“0”]

]

输出:1

示例 2:

输入:grid = [

[“1”,“1”,“0”,“0”,“0”],

[“1”,“1”,“0”,“0”,“0”],

[“0”,“0”,“1”,“0”,“0”],

[“0”,“0”,“0”,“1”,“1”]

]

输出:3

题目来源:力扣(LeetCode)

dfs思路

能否写出:能写出。

时间:15分钟多

思路:

遍历整个二维数组,对于每个位置,如果该位置为陆地(‘1’),则进行dfs搜索,将与该位置相连的所有陆地标记为水域(‘0’),并将岛屿数量加1。

dfs函数中的边界条件判断部分是非常重要的,为了确保在进行深度优先搜索时,不会出现越界访问的情况,同时也可以提前剪枝,避免不必要的搜索操作。

判断当前位置 (x, y) 是否越界或者是否已经被访问过(标记为水域 '0'

  • x < 0:如果 x 坐标小于 0,表示当前位置超出了数组的上边界。
  • y < 0:如果 y 坐标小于 0,表示当前位置超出了数组的左边界。
  • x >= row:如果 x 坐标大于或等于行数 row,表示当前位置超出了数组的下边界。
  • y >= col:如果 y 坐标大于或等于列数 col,表示当前位置超出了数组的右边界。
  • grid[x][y] == '0':如果当前位置的值为 '0',表示当前位置已经被访问过,即为水域。
// 仅是我的思路代码,leetcode上大神更厉害
class Solution {
    public int numIslands(char[][] grid) {
        //获取行数
        int row = grid.length;
        //获取列数
        int col = grid[0].length;
        int res = 0;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (grid[i][j] == '1') {
                    res++;
                    dfs(grid, i, j, row, col);
                }
            }
        }
        return res;
    }
    public void dfs(char[][] grid, int x, int y, int row, int col) {
        //边界条件判断
        if (x < 0 || y < 0 || x >= row || y >= col || grid[x][y] == '0') {
            return;
        }
        grid[x][y] = '0';
        dfs(grid, x + 1, y, row, col);
        dfs(grid, x - 1, y, row, col);
        dfs(grid, x, y + 1, row, col);
        dfs(grid, x, y - 1, row, col);
    }
}

时间复杂度:O(MN)

  • 分别是行数和列数

空间复杂度:O(MN)

  • 如果整个二维数组都是陆地,那么dfs深度达到MN

其他思路

bfs:

class Solution {
    public int numIslands(char[][] grid) {
        int row = grid.length;
        int col = grid[0].length;
        int count = 0;
        // 创建一个队列用于存储待访问的位置
        Queue<int[]> queue = new LinkedList<>();
        // 遍历整个网格
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (grid[i][j] == '1') {
                    // 找到一个岛屿,将其标记为已访问,并加入队列
                    count++;
                    bfs(grid, row, col, queue, i, j);
                }
            }
        }
        return count;
    }
    private void bfs(char[][] grid, int row, int col, Queue<int[]> queue, int i, int j) {
        grid[i][j] = '0';
        queue.offer(new int[]{i, j});
        // 开始进行广度优先搜索
        while (!queue.isEmpty()) {
            int[] curr = queue.poll();
            int x = curr[0];
            int y = curr[1];
            if (x - 1 >= 0 && grid[x - 1][y] == '1') {
                queue.add(new int[]{x - 1, y});
                grid[x - 1][y] = '0';
            }
            if (y - 1 >= 0 && grid[x][y - 1] == '1') {
                queue.add(new int[]{x, y - 1});
                grid[x][y - 1] = '0';
            }
            if (x + 1 < row && grid[x + 1][y] == '1') {
                queue.add(new int[]{x + 1, y});
                grid[x + 1][y] = '0';
            }
            if (y + 1 < col && grid[x][y + 1] == '1') {
                queue.add(new int[]{x, y + 1});
                grid[x][y + 1] = '0';
            }
        }
    }
}

时间复杂度:O(MN)

空间复杂度:O(MN)

相关文章
|
1月前
|
算法 测试技术 定位技术
数据结构与算法——DFS(深度优先搜索)
数据结构与算法——DFS(深度优先搜索)
|
1月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
38 0
|
3月前
|
算法
DFS算法的实现
DFS算法的实现
61 3
|
14天前
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
|
1月前
|
算法
每日一道算法题(Leetcode 20)
每日一道算法题(Leetcode 20)
26 2
|
3月前
|
算法 Java
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
52 6
|
3月前
|
人工智能 算法 Java
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
50 1
|
3月前
|
存储 算法 Java
LeetCode经典算法题:预测赢家+香槟塔java解法
LeetCode经典算法题:预测赢家+香槟塔java解法
61 1
|
3月前
|
存储 算法 Java
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
79 0
|
3月前
|
算法 Java
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
43 0
下一篇
无影云桌面