想要精通算法和SQL的成长之路 - 岛屿数量和岛屿的最大面积

想要精通算法和SQL的成长之路 - 岛屿数量和岛屿的最大面积

  • 前言
  • 一. 岛屿数量
    • 1.1 并查集数据结构构造
    • 1.2 使用并查集编码
  • 二. 岛屿的最大面积

前言

想要精通算法和SQL的成长之路 - 系列导航
并查集的运用

一. 岛屿数量

原题链接

在这里插入图片描述

从这个题目的特性来看,它适合用并查集来解决。对并查集还不清楚的,可以看下前言里面的链接。

1.1 并查集数据结构构造

这里的难点就是:

  • 如何将二维数组转化为一维数组。假设二维数组下标(i,j),长len1,高len2.
  • 那么二维下标转化为一维坐标就是:i*len2 + j
class UnionFind {private int[] parent;private int[] rank;private int sum;public UnionFind(char[][] grid) {// 初始化岛屿数量为0,因为我们还没有遍历数组,不知道岛屿的数量sum = 0;int len1 = grid.length;int len2 = grid[0].length;parent = new int[len1 * len2];rank = new int[len1 * len2];for (int i = 0; i < len1; i++) {for (int j = 0; j < len2; j++) {// 根节点指向自己parent[i * len2 + j] = i * len2 + j;// 如果这个地方是岛屿,那么该元素对应的集合内元素数量为1if (grid[i][j] == '1') {rank[i * len2 + j] = 1;// 岛屿数量+1sum++;}}}}public int find(int x) {while (x != parent[x]) {x = parent[x];}return x;}public void union(int x, int y) {int rootX = find(x);int rootY = find(y);if (rootX == rootY) {return;}// 如果根节点 rootX 的深度 > rootY。if (rank[rootX] > rank[rootY]) {// 那么将以rootY作为根节点的集合加入到rootX对应的集合当中rank[rootX] += rank[rootY];// 同时改变rootY的根节点,指向rootX。parent[rootY] = rootX;} else {// 反之rank[rootY] += rank[rootX];parent[rootX] = rootY;}// 岛屿数量-1sum--;}
}

1.2 使用并查集编码

public int numIslands(char[][] grid) {int len1 = grid.length;int len2 = grid[0].length;UnionFind unionFind = new UnionFind(grid);for (int i = 0; i < len1; i++) {for (int j = 0; j < len2; j++) {// 如果当前是岛屿if (grid[i][j] == '1') {// 先将当前的岛屿标识改变,避免被重复访问grid[i][j] = '0';// 分别朝4个方向,上下左右访问,如果是岛屿,开始合并if (i - 1 >= 0 && grid[i - 1][j] == '1') {unionFind.union(i * len2 + j, (i - 1) * len2 + j);}if (i + 1 < len1 && grid[i + 1][j] == '1') {unionFind.union(i * len2 + j, (i + 1) * len2 + j);}if (j - 1 >= 0 && grid[i][j - 1] == '1') {unionFind.union(i * len2 + j, i * len2 + j - 1);}if (j + 1 < len2 && grid[i][j + 1] == '1') {unionFind.union(i * len2 + j, i * len2 + j + 1);}}}}// 最后返回岛屿的数量return unionFind.sum;
}

最终完整代码如下:

public class Test200 {public int numIslands(char[][] grid) {int len1 = grid.length;int len2 = grid[0].length;UnionFind unionFind = new UnionFind(grid);for (int i = 0; i < len1; i++) {for (int j = 0; j < len2; j++) {// 如果当前是岛屿if (grid[i][j] == '1') {// 先将当前的岛屿标识改变,避免被重复访问grid[i][j] = '0';// 分别朝4个方向,上下左右访问,如果是岛屿,开始合并if (i - 1 >= 0 && grid[i - 1][j] == '1') {unionFind.union(i * len2 + j, (i - 1) * len2 + j);}if (i + 1 < len1 && grid[i + 1][j] == '1') {unionFind.union(i * len2 + j, (i + 1) * len2 + j);}if (j - 1 >= 0 && grid[i][j - 1] == '1') {unionFind.union(i * len2 + j, i * len2 + j - 1);}if (j + 1 < len2 && grid[i][j + 1] == '1') {unionFind.union(i * len2 + j, i * len2 + j + 1);}}}}// 最后返回岛屿的数量return unionFind.sum;}class UnionFind {private int[] parent;private int[] rank;private int sum;public UnionFind(char[][] grid) {// 初始化岛屿数量为0,因为我们还没有遍历数组,不知道岛屿的数量sum = 0;int len1 = grid.length;int len2 = grid[0].length;parent = new int[len1 * len2];rank = new int[len1 * len2];for (int i = 0; i < len1; i++) {for (int j = 0; j < len2; j++) {// 根节点指向自己parent[i * len2 + j] = i * len2 + j;// 如果这个地方是岛屿,那么该元素对应的集合内元素数量为1if (grid[i][j] == '1') {rank[i * len2 + j] = 1;// 岛屿数量+1sum++;}}}}public int find(int x) {while (x != parent[x]) {x = parent[x];}return x;}public void union(int x, int y) {int rootX = find(x);int rootY = find(y);if (rootX == rootY) {return;}// 如果根节点 rootX 的深度 > rootY。if (rank[rootX] > rank[rootY]) {// 那么将以rootY作为根节点的集合加入到rootX对应的集合当中rank[rootX] += rank[rootY];// 同时改变rootY的根节点,指向rootX。parent[rootY] = rootX;} else {// 反之rank[rootY] += rank[rootX];parent[rootX] = rootY;}// 岛屿数量-1sum--;}}
}

二. 岛屿的最大面积

原题链接

在这里插入图片描述
在这里插入图片描述

这个题目就是在第一题的基础上,查找最大的集合深度,即rank的最大值。我们只需要在第一题的基础上,增加一个循环判断即可:

int maxArea = 0;
for (int i = 0; i < len1 * len2; i++) {maxArea = Math.max(maxArea, unionFind.rank[i]);
}
return maxArea;

注意:

  • 本题是int类型的数组,你可以全局替换一下字符:将 ' 替换成 char 替换成int

最终完整代码如下:

public class Test695 {public int maxAreaOfIsland(int[][] grid) {int len1 = grid.length;int len2 = grid[0].length;UnionFind unionFind = new UnionFind(grid);for (int i = 0; i < len1; i++) {for (int j = 0; j < len2; j++) {// 如果当前是岛屿if (grid[i][j] == 1) {// 先将当前的岛屿标识改变,避免被重复访问grid[i][j] = 0;// 分别朝4个方向,上下左右访问,如果是岛屿,开始合并if (i - 1 >= 0 && grid[i - 1][j] == 1) {unionFind.union(i * len2 + j, (i - 1) * len2 + j);}if (i + 1 < len1 && grid[i + 1][j] == 1) {unionFind.union(i * len2 + j, (i + 1) * len2 + j);}if (j - 1 >= 0 && grid[i][j - 1] == 1) {unionFind.union(i * len2 + j, i * len2 + j - 1);}if (j + 1 < len2 && grid[i][j + 1] == 1) {unionFind.union(i * len2 + j, i * len2 + j + 1);}}}}int maxArea = 0;for (int i = 0; i < len1 * len2; i++) {maxArea = Math.max(maxArea, unionFind.rank[i]);}return maxArea;}class UnionFind {private int[] parent;private int[] rank;private int sum;public UnionFind(int[][] grid) {// 初始化岛屿数量为0,因为我们还没有遍历数组,不知道岛屿的数量sum = 0;int len1 = grid.length;int len2 = grid[0].length;parent = new int[len1 * len2];rank = new int[len1 * len2];for (int i = 0; i < len1; i++) {for (int j = 0; j < len2; j++) {// 根节点指向自己parent[i * len2 + j] = i * len2 + j;// 如果这个地方是岛屿,那么该元素对应的集合内元素数量为1if (grid[i][j] == 1) {rank[i * len2 + j] = 1;// 岛屿数量+1sum++;}}}}public int find(int x) {while (x != parent[x]) {x = parent[x];}return x;}public void union(int x, int y) {int rootX = find(x);int rootY = find(y);if (rootX == rootY) {return;}// 如果根节点 rootX 的深度 > rootY。if (rank[rootX] > rank[rootY]) {// 那么将以rootY作为根节点的集合加入到rootX对应的集合当中rank[rootX] += rank[rootY];// 同时改变rootY的根节点,指向rootX。parent[rootY] = rootX;} else {// 反之rank[rootY] += rank[rootX];parent[rootX] = rootY;}// 岛屿数量-1sum--;}}
}

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

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

相关文章

用Python操作PPT的办公自动化教程

PPT通过其精美的可视化技巧以及良好的演示效果&#xff0c;成为了职场人士的必备技能。PPT的设计是一门大学问&#xff0c;无论是设计技巧&#xff0c;还是操作方法&#xff0c;都衍生出了专门的课程。 主要介绍Python操作PPT的技巧&#xff0c;编程的优势在于处理速度&#x…

10分钟了解数据架构、数据模型

写在前面&#xff1a;很多小伙伴分不清数据架构与数据模型&#xff0c;同时如何做好数据建模也有一定的疑问 1. 数据架构、数据模型、数据建模区别与联系 企业架构包含业务架构、数据架构、应用架构和技术架构。数据架构的主要目标是有效的管理数据&#xff0c;以及有效地管理…

(三) gitblit管理员手册

(一)gitblit安装教程 (二) gitblit用户使用教程 (三) gitblit管理员手册 目录 权限管理创建仓库时创建用户普通用户 管理员用户访问限制和访问权限仓库创建权限分配 Teams普通组管理员组 参考资料 权限管理 创建仓库时 选择指定的人员查看,克隆,推送 不允许fork 对应Anonymo…

十、2023.10.4.计算机网络(one).10

文章目录 1、简述静态路由和动态路由&#xff1f;2、说说有哪些路由协议&#xff0c;都是如何更新的&#xff1f;3、简述域名解析过程&#xff0c;本机如何干预域名解析&#xff1f;4、简述 DNS 查询服务器的基本流程是什么&#xff1f;DNS 劫持是什么&#xff1f;5、简述网关的…

Docker从认识到实践再到底层原理(九)|Docker Compose 容器编排

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…

Nacos与Eureka的区别

大家好我是苏麟今天说一说Nacos与Eureka的区别. Nacos Nacos的服务实例分为两种l类型&#xff1a; 临时实例&#xff1a;如果实例宕机超过一定时间&#xff0c;会从服务列表剔除&#xff0c;默认的类型。非临时实例&#xff1a;如果实例宕机&#xff0c;不会从服务列表剔除&…

十天学完基础数据结构-第四天(链表(Linked List))

链表的基本概念 链表是一种线性数据结构&#xff0c;与数组不同&#xff0c;链表的元素&#xff08;节点&#xff09;之间通过指针相互连接。链表有以下基本概念&#xff1a; 节点&#xff1a;链表中的每个数据项称为节点&#xff0c;每个节点包含数据和一个指向下一个节点的指…

2023年中国智能电视柜产量、需求量、市场规模及行业价格走势[图]

电视柜是随着电视机的发展和普及而演变出的家具种类&#xff0c;其主要作用是承载电视机&#xff0c;又称视听柜&#xff0c;随着生活水平的提高&#xff0c;与电视机相配套的电器设备也成为电视柜的收纳对象。 随着智能家具的发展&#xff0c;智能电视机柜的造型和风格都是有了…

GhostNet原理解析及pytorch实现

论文&#xff1a;https://arxiv.org/abs/1911.11907 源码&#xff1a;https://github.com/huawei-noah/ghostnet 简要论述GhostNet的核心内容。 Ghost Net 1、Introduction 在训练良好的深度神经网络的特征图中&#xff0c;丰富甚至冗余的信息通常保证了对输入数据的全面理…

4.Tensors For Beginners-Vector Definition

在上一节&#xff0c;已经了解了前向和后向转换。 什么是向量&#xff1f; 定义1&#xff1a;向量是一个数字列表 这很简洁&#xff0c;也通俗易懂。 现有两个向量&#xff1a; 如果要把这两个向量给加起来&#xff0c;只需把对应位置的元素(组件)给加起来。 而要缩放向量&…

微服务技术栈-初识Docker

文章目录 前言一、Docker概念二、安装Docker三、Docker服务命令四、Docker镜像和容器Docker镜像相关命令Docker容器相关命令 总结 前言 docker技术风靡全球&#xff0c;它的功能就是将linux容器中的应用代码打包,可以轻松的在服务器之间进行迁移。docker运行程序的过程就是去仓…

视频增强修复工具Topaz Video AI mac中文版安装教程

Topaz Video AI mac是一款使用人工智能技术对视频进行增强和修复的软件。它可以自动降噪、去除锐化、减少压缩失真、提高清晰度等等。Topaz Video AI可以处理各种类型的视频&#xff0c;包括低分辨率视频、老旧影片、手机录制的视频等等。 使用Topaz Video AI非常简单&#xff…

Java开源工具库使用之Lombok

文章目录 前言一、常用注解1.1 AllArgsConstructor/NoArgsConstructor/RequiredArgsConstructor1.2 Builder1.3 Data1.4 EqualsAndHashCode1.5 Getter/Setter1.6 Slf4j/Log4j/Log4j2/Log1.7 ToString 二、踩坑2.1 Getter/Setter 方法名不一样2.2 Builder 不会生成无参构造方法2…

混合优化算法(optimtool.hybrid)

import optimtool as oo from optimtool.base import np, sp, pltpip install optimtool>2.5.0混合优化算法&#xff08;optimtool.hybrid&#xff09; import optimtool.hybrid as oh oh.[方法名].[函数名]([目标函数], [参数表], [初始迭代点], [正则化参数], [邻近算子名…

无约束优化方法(optimtool.unconstrain)

import optimtool as oo from optimtool.base import np, sp, pltpip install optimtool >2.4.2无约束优化方法&#xff08;optimtool.unconstrain&#xff09; import optimtool.unconstrain as ou ou.[方法名].[函数名]([目标函数], [参数表], [初始迭代点])f ( x ) ∑ …

数据结构和算法——数据结构

数据结构&#xff1a; 线性结构&#xff1a; 顺序存储方式&#xff0c;顺序表 常见的顺序存储结构有&#xff1a;数组、队列、链表、栈 链式存储方式&#xff0c;链表 队列&#xff1a; 队列可以使用数组结构或者链表结构来存储&#xff0c;先入先出&#xff0c;后进后出。…

如何使用大语言模型来绘制图画

请创作一张科技感十足的图片&#xff0c;包含siri和iphone两个元素&#xff0c;请帮我挑选合适的style和background 好的&#xff0c;我会为你创作一张科技感十足的图片&#xff0c;包含siri和iphone两个元素。我会根据你的要求&#xff0c;选择一种适合的风格和背景。请稍等一…

智能AI创作系统ChatGPT商业运营版源码+AI绘画系统/支持GPT联网提问/支持Midjourney绘画+Prompt应用+支持国内AI提问模型

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧&…

(五)激光线扫描-位移台标定

线激光属于主动测量方式,但是由于线激光的特性,我们只能通过提取激光中心线获取这一条线上的高度信息,那么要进行三维重建的话,就需要通过平移或者是旋转的方式,来让线激光扫描被测物体的完整轮廓,也就是整个表面。激光线的密度越高还原出来的物体越细腻,但由于数据量大…

RabbitMQ-发布订阅模式和路由模式

接上文 RabbitMQ-工作队列 1 发布订阅模式 将之前的配置类内容都替换掉 Bean("fanoutExchange")public Exchange exchange(){//注意这里是fanoutExchangereturn ExchangeBuilder.fanoutExchange("amq.fanout").build();}Bean("yydsQueue1")publ…