Python面试宝典第15题:岛屿数量

news2024/9/17 7:08:54

题目

        在二维网格地图上,'1' 表示陆地,'0' 表示水域。如果相邻的陆地可以水平或垂直连接,则它们属于同一块岛屿。请进行编码,统计地图上的岛屿数量。比如:下面的二维网格地图,其岛屿数量为3。

基础知识

        解决这类问题的一种常见方法是:深度优先搜索(DFS)或广度优先搜索(BFS)。深度优先搜索和广度优先搜索是图和树型结构中两种基本的遍历算法,广泛应用于各种问题解决场景中,比如:路径查找、图的连通性分析、游戏AI等。下面,我们介绍下深度优先搜索和广度优先搜索的基础知识。

        深度优先搜索是一种探索策略,算法会尽可能深地探索图的分支,直到到达叶子节点或无法继续深入为止,然后回溯以探索其他分支。这个过程类似于树的前序遍历,先访问子节点,再返回访问兄弟节点。深度优先搜索通常使用递归来实现,也可以通过栈来手动模拟递归过程。在遍历过程中,一旦访问到一个未访问过的节点,就标记该节点为已访问,并继续深入访问其子节点。

        广度优先搜索则是从起始节点开始,一层一层地往外探索。先访问离起点最近的所有节点,再访问次近的节点,以此类推。这个过程,类似于树的层次遍历。广度优先搜索主要利用队列数据结构来实现:从根节点开始,将其放入队列中,然后从队列中取出节点并访问;接着,将该节点的所有未访问过的邻接节点放入队列,重复这一过程直到队列为空。

深度优先搜索算法

        我们首先使用深度优先搜索(DFS)算法来求解本题。DFS是一种递归算法,用于遍历或搜索树或图的数据结构。在本题中,我们可以将每个‘1’视为图中的一个节点,相邻的‘1’之间存在边。我们的目标是遍历所有与当前节点相连的陆地节点,并避免重复计数。使用DFS求解本题的主要步骤如下。

        1、初始化计数器。设置一个岛屿计数器,初始值为0。

        2、遍历网格。遍历整个二维网格的每一个元素,当遇到值为‘1’的元素时,进行以下操作。

        (1)增加岛屿计数器的值。

        (2)对该位置调用以下的DFS函数,以探索与之相连的所有陆地。

        (3)在DFS过程中,将访问过的陆地标记为其他值,以防止重复计数。

        3、DFS函数,功能如下。

        (1)输入一个坐标,检查该坐标是否在网格内且值为‘1’,如果不是则返回。

        (2)将当前位置标记为已访问(比如:改为‘2’)。

        (3)递归地对当前位置的上、下、左、右邻居进行DFS,确保只访问未标记的陆地。

        4、完成遍历:当整个网格遍历完成后,计数器的值即为岛屿总数。

        根据上面的算法步骤,我们可以得出下面的示例代码。

def dfs(grid, row, col):
    if row < 0 or col < 0 or row >= len(grid) or \
        col >= len(grid[0]) or grid[row][col] != '1':
        return
    
    # 标记为已访问
    grid[row][col] = '2'
    # 向下
    dfs(grid, row + 1, col)
    # 向上
    dfs(grid, row - 1, col)
    # 向右
    dfs(grid, row, col + 1)
    # 向左
    dfs(grid, row, col - 1)

def island_count_by_dfs(grid):
    count = 0
    for row in range(len(grid)):
        for col in range(len(grid[0])):
            if grid[row][col] == '1':
                count += 1
                dfs(grid, row, col)
    return count

grid = [
    ['1', '1', '0', '0', '0'],
    ['1', '1', '0', '0', '0'],
    ['0', '0', '1', '0', '0'],
    ['0', '0', '0', '1', '1']
]
print(island_count_by_dfs(grid))

广度优先搜索算法

        接下来,我们使用广度优先搜索(BFS)算法来求解本题。BFS通过队列逐层探索二维网格地图,标记访问过的陆地,从而逐个发现并计数岛屿。使用BFS求解本题的主要步骤如下。

        1、初始化。设立一个队列用于BFS遍历,以及一个计数器来记录岛屿数量。

        2、遍历网格。遍历整个二维网格,对于每个元素,如果遇到值为‘1’的(表示陆地),进行以下操作。

        (1)增加岛屿计数器。

        (2)将此陆地坐标放入队列中,并将其标记为已访问(比如:改为‘2’)。

        (3)开始BFS,从当前坐标出发,探索所有相连的陆地。

        3、BFS过程,大致步骤如下。

        (1)从队列中取出一个坐标。

        (2)探索其上、下、左、右四个相邻坐标。

        (3)对于每个未访问的陆地邻居,将其标记为已访问,并加入队列。

        (4)重复上述过程,直到队列为空。

        根据上面的算法步骤,我们可以得出下面的示例代码。

from collections import deque

def bfs(grid, row, col):
    queue = deque([(row, col)])
    directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
    
    while queue:
        r, c = queue.popleft()
        for dr, dc in directions:
            new_r, new_c = r + dr, c + dc
            if 0 <= new_r < len(grid) and 0 <= new_c < len(grid[0]) \
                and grid[new_r][new_c] == '1':
                grid[new_r][new_c] = '2'
                queue.append((new_r, new_c))

def island_count_by_bfs(grid):
    island_count = 0
    for row in range(len(grid)):
        for col in range(len(grid[0])):
            if grid[row][col] == '1':
                island_count += 1
                bfs(grid, row, col)
    return island_count

grid = [
    ['1', '1', '0', '0', '0'],
    ['1', '1', '0', '0', '0'],
    ['0', '0', '1', '0', '0'],
    ['0', '0', '0', '1', '1']
]
print(island_count_by_bfs(grid))

总结

        可以看到,无论是DFS还是BFS,时间复杂度均为O(M * N),空间复杂度在最坏情况下为O(M)或O(N),取决于地图的具体布局和岛屿的分布情况。其中,M是网格的行数,N是网格的列数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1935300.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux入门以及Linux文件编程学习

Linux学习必备 首先我们学习Linux必须安装一个虚拟机&#xff0c;我是跟着韦东山老师安装的&#xff0c;具体可以跟着视频操作&#xff0c;简单易懂&#xff1a;安装虚拟机 Linux入门最基本简单的指令 一、Vi的使用 Vi文件名 创建或者打开一个文件&#xff0c;进入默认命令行…

[论文笔记] pai-megatron-patch Qwen2-CT 长文本rope改yarn

更改: # Copyright (c) 2024 Alibaba PAI and Nvidia Megatron-LM Team. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License a…

Linux——多路复用之select

目录 前言 一、select的认识 二、select的接口 三、select的使用 四、select的优缺点 前言 在前面&#xff0c;我们学习了五种IO模型&#xff0c;对IO有了基本的认识&#xff0c;知道了select效率很高&#xff0c;可以等待多个文件描述符&#xff0c;那他是如何等待的呢&a…

JavaScript 获取 url(get)参数

https://andi.cn/page/621584.html

Gitee 使用教程1-SSH 公钥设置

一、生成 SSH 公钥 1、打开终端&#xff08;Windows PowerShell 或 Git Bash&#xff09;&#xff0c;通过命令 ssh-keygen 生成 SSH Key&#xff1a; ssh-keygen -t ed25519 -C "Gitee SSH Key" 随后摁三次回车键&#xff08;Enter&#xff09; 2、查看生成的 SSH…

大鲸鱼docker-compose单机容器集群编排工具

目录 一、Docker-compose 概述 二、Docker-compose简介 三、YML文件格式及编写注意事项 1.yml文件是什么 2.yml问价使用注意事项 3.yml文件的基本数据结构 四、Docker-compose 配置 1.Docker-Compose 配置常用字段 2.Docker Compose常用命令 3.使用Docker-compose创建…

Python解释器:CPython 解释器

一、什么是python解释器 Python解释器是一种用于执行Python代码的程序。 它将Python源代码转换为机器语言或字节码&#xff0c;从而使计算机能够执行。 1.1 Python解释器分类 1、CPython CPython 是 Python 的主要实现&#xff0c;由 C 语言编写。大多数用户在日常开发中使…

django实现用户的注册、登录、注销功能

创建django项目的步骤&#xff1a;Django项目的创建步骤-CSDN博客 一、前置工作 配置数据库&#xff0c;设置数据库引擎为mysql 1、在settings文件中找到DATABASES, 配置以下内容 DATABASES {"default": {ENGINE: django.db.backends.mysql, # 数据库引擎NAME: dja…

色彩与故乡的对话 —— 钱华个人油画展正式开展

色彩与故乡的对话 —— 钱华个人油画展正式开展 2024年7月17日 &#xff0c;在宁波这座历史与现代交织的城市里&#xff0c;艺术与文化的碰撞再次绽放出耀眼的光芒。由宁波海曙区美术家协会主办&#xff0c;宁波市海纳广场开发经营有限公司协办的“色彩与故乡的对话——钱华个人…

【SpringBoot Web开发之静态资源访问】笔记

详细内容见官方文档&#xff1a;Static Content SpringBoot Web开发之静态资源访问 1.准备工作&#xff1a;创建WebDemo2.静态资源目录2.1官网原文2.2静态资源目录第一步&#xff1a;依照上面2.1官网原文中创建如下目录第二步&#xff1a;复制粘贴图片到静态资源目录中第三步…

二叉树的前、中、后序遍历(递归法、迭代法)leetcode144/94/145

leetcode144、二叉树的前序遍历 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,2,3] 示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[] 示例 3&#xff1a;…

海外媒体发稿-瑞典SEO破茧成蝶:从0到10的实战精要-大舍传媒

海外媒体发稿-瑞典SEO破茧成蝶:从0到10的实战精要 一、迷茫与意义的探寻 有一天我找了王老师聊天&#xff0c;谈到生活迷茫和人生的意义。老师说了一段话&#xff1a;当全情投入于一件事情时&#xff0c;是没有时间去迷茫或思索人生意义的。我感触很深&#xff0c;当总感到迷…

UI设计中的响应式布局策略:让您的界面在各种设备上都表现出色

UI界面设计它是人与机器之间交互的媒介&#xff0c;也是客户体验的媒介&#xff08;UX&#xff09;一个组成部分。操作界面由两个主要部分组成&#xff1a;视觉设计&#xff08;即传达产品的外观和感觉&#xff09;和交互设计&#xff08;即元素功能和逻辑组织&#xff09;。用…

自定义注解 + Redis 实现业务的幂等性

1.实现幂等性思路 实现幂等性有两种方式&#xff1a; ⭐ 1. 在数据库层面进行幂等性处理&#xff08;数据库添加唯一约束&#xff09;. 例如&#xff1a;新增用户幂等性处理&#xff0c;username 字段可以添加唯一约束. ⭐ 2. 在应用程序层面进行幂等性处理. 而在应用程序…

Go语言并发编程-Channel通信_2

Channel通信 Channel概述 不要通过共享内存的方式进行通信&#xff0c;而是应该通过通信的方式共享内存 这是Go语言最核心的设计模式之一。 在很多主流的编程语言中&#xff0c;多个线程传递数据的方式一般都是共享内存&#xff0c;而Go语言中多Goroutine通信的主要方案是Cha…

人工智能算法工程师(高级)课程1-单类目标识别之人脸检测识别技术MTCNN模型介绍与代码详解

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能算法工程师(高级)课程1-单类目标识别之人脸检测识别技术MTCNN模型介绍与代码详解。本文深入探讨了基于PyTorch的人脸检测与识别技术&#xff0c;详细介绍了MTCNN模型、Siamese network以及center loss、sof…

趣谈linux操作系统 9 网络系统-读书笔记

文章目录 网络协议栈基础知识回顾网络分层网络分层的目的各层作用简介延伸-ip地址,有类,无类,cidr socket实现分析tcp/udp回顾socket编程回顾TCP编程回顾UDP编程回顾差异 socket相关接口实现浅析sokcet实现解析创建socket的三个参数socket函数定义及其参数创建socket结构体关联…

element UI :el-table横向列内容超出宽度,滚动条不显示问题

是否能解决你问题的前提 **看到这篇文章的解决问题的方案之前&#xff0c;请先回忆你是否在项目中的全局样式或者私有组件中去单独设置过滚动条样式。如果有 请继续往下看&#xff1a;**单独设置过滚动条样式代码实例&#xff1a; ::-webkit-scrollbar {/*滚动条整体样式*/wi…

STM32智能家居电力管理系统教程

目录 引言环境准备智能家居电力管理系统基础代码实现&#xff1a;实现智能家居电力管理系统 4.1 数据采集模块 4.2 数据处理与控制模块 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;电力管理与优化问题解决方案与优化收尾与总结 1. 引言 智能家居电…

代码随想录——最后一块石头的重量(Leetcode1046)

题目链接 class Solution {public int lastStoneWeight(int[] stones) {int len stones.length;if(len 1){return stones[0];}if(len 2){return Math.abs(stones[0] - stones[1]);}while(true){Arrays.sort(stones);if(stones[len - 2] 0){break;}stones[len - 1] stone…