序言
虽然算法很难,但不应该就放弃。这是一个学习笔记,希望你们喜欢~
先自己尝试写,大概十几分钟仍然写不出来
看思路,再尝试跟着思路写
仍然写不出来,再看视频
b站up视频推荐:爱学习的饲养员
leetcode其他文章:
数组篇:
链表篇:
从小白开始刷算法 ListNode 链表篇 leetcode.203
从小白开始刷算法 ListNode 链表篇 leetcode.206
队列篇
从小白开始刷算法 ListNode 链表篇 leetcode.933
栈篇
从小白开始刷算法 Stack 栈篇 leetcode.496
哈希篇
从小白开始刷算法 Hash 哈希篇 leetcode.217
从小白开始刷算法 Hash 哈希篇 leetcode.705
树篇
从小白开始刷算法 Tree 树篇 先序遍历 leetcode.144
从小白开始刷算法 Tree 树篇 中序遍历 leetcode.94
从小白开始刷算法 Tree 树篇 后序遍历 leetcode.94
堆篇
从小白开始刷算法 Heap 堆篇 最大堆排序 leetcode.215
小白开始刷算法 Heap 堆篇 最小堆排序 leetcode.692
双指针篇
二分法篇
滑动窗口篇
递归篇
分治法篇
回溯法篇
dfs篇
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)