两百天两百题大挑战之1——岛屿数量

200. 岛屿数量 【中等题】【深搜&广搜】

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

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

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

输入:
[
['1','1','1','1','0'],
['1','1','0','1','0'],
['1','1','0','0','0'],
['0','0','0','0','0']
]
输出: 1

输入:
[
['1','1','0','0','0'],
['1','1','0','0','0'],
['0','0','1','0','0'],
['0','0','0','1','1']
]
输出: 3
解释: 每座岛屿只能由水平和/或竖直方向上相邻的陆地连接而成。

题目讲解

解法1:深搜解法

【核心思想】

  • 从一个点出发,遇到第一个’1’,岛屿总数就+1。然后利用深搜,将这片岛屿都变成海洋,即将1都变成0。然后继续找下一个岛屿

【数据结构】

  • 数组

【思路】

  • 循环遍历grid,遇到第一个’1’,岛屿总数就+1
  • 利用深搜遍历这一个岛屿,将遍历过的岛屿都置为’0’。当某一点四周都是’0’时,则返回(这一步是想将这片岛屿都变成海洋)
  • 找下一个岛屿,重复上面的操作

【代码】

 class Solution {
     
    public int numIslands(char[][] grid) {
     
        if (grid == null || grid.length == 0) {
     
            return 0;
        }
        int nums = 0;
        for (int i = 0; i < grid.length; i++) {
     
            for (int j = 0; j < grid[0].length; j++) {
     
                if (grid[i][j] == '1') {
     
                    nums++;
                    dfs(grid, i, j);
                }
            }
        }
        return nums;
    }

    void dfs(char[][] grid, int i, int j) {
     
        if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length || grid[i][j] == '0') {
     
            return;
        }
        grid[i][j] = '0';
        dfs(grid, i - 1, j);
        dfs(grid, i + 1, j);
        dfs(grid, i, j - 1);
        dfs(grid, i, j + 1);
    }
}

【备注】

  • 能用深搜做的题目,基本都能用广搜。而深搜转化为广搜的本质就是递归变成迭代,需要利用一个数据结构,这里,我们用队列
public List<Integer> rightSideView(TreeNode root) {
     
    if(root==null)
        return new ArrayList<>();
    Queue<TreeNode> queue=new ArrayDeque<>();
    List<Integer> list=new ArrayList<>();
    queue.add(root);
    while(!queue.isEmpty()){
     
        list.add(queue.peek().val);
        int len=queue.size();
        for(int i=0;i<len;i++){
     
            TreeNode temp=queue.poll();
            if(temp.right!=null)
                queue.add(temp.right);
            if(temp.left!=null)
                queue.add(temp.left);
        }
    }
    return list;
}

解法2:递归解法

【核心思想】

  • 每一层只有一个结点的val需要加入list,所以可以用一个变量level控制

【思路】

  • 在调用递归函数时,先调度用右结点,再调用左结点
  • level == ans.size(),即已经遇到了这一层最右边的结点,将其val加入list即可

【代码】

List<Integer> list = new ArrayList<>();
public List<Integer> rightSideView(TreeNode root) {
     
    help(root, 0);
    return list;
}
void help(TreeNode root, int level) {
     
    if (root == null)
        return;
    if (level == list.size())
        list.add(root.val);
    help(root.right, level + 1);
    help(root.left, level + 1);
}

关注微信公众号“算法岗从零到无穷”,更多算法知识点告诉你。

在这里插入图片描述

你可能感兴趣的:(一天一道算法题)