LeetCode题练习与总结:安装栅栏--587
一、题目描述
给定一个数组 trees,其中 trees[i] = [xi, yi] 表示树在花园中的位置。
你被要求用最短长度的绳子把整个花园围起来,因为绳子很贵。只有把 所有的树都围起来,花园才围得很好。
返回恰好位于围栏周边的树木的坐标。
示例 1:

输入: points = [[1,1],[2,2],[2,0],[2,4],[3,3],[4,2]] 输出: [[1,1],[2,0],[3,3],[2,4],[4,2]]
示例 2:

输入: points = [[1,2],[2,2],[4,2]] 输出: [[4,2],[2,2],[1,2]]
注意:
1 <= points.length <= 3000points[i].length == 20 <= xi, yi <= 100-
所有给定的点都是 唯一 的。
二、解题思路
这个问题是计算几何中的经典问题,称为“凸包问题”。凸包是包含所有给定点的最小凸多边形。在这个问题中,树木的位置是给定的点,我们需要找到这些点的凸包,这个凸包的顶点就是我们要找的树木坐标。
解决这个问题的常用算法有几种,比如“Graham扫描”和“Andrew扫描”。这里我将使用“Graham扫描”算法来解决这个问题,因为它相对简单且易于实现。
Graham扫描算法的步骤如下:
- 找到所有点中y坐标最小的点,如果有多个这样的点,则选择x坐标最小的点作为起点。
- 将所有点按照极角(相对于起点)进行排序。
- 从起点开始,按顺序遍历每个点,检查当前点是否使凸包的拐向从左到右。如果是,则将当前点添加到凸包中;如果不是,则移除前一个点,因为它不在凸包上。
- 重复步骤3,直到所有点都被处理。
三、具体代码
import java.util.*;class Solution {public int[][] outerTrees(int[][] trees) {if (trees.length <= 1) return trees;// Step 1: Find the starting pointint start = 0;for (int i = 1; i < trees.length; i++) {if (trees[i][1] < trees[start][1] || (trees[i][1] == trees[start][1] && trees[i][0] < trees[start][0])) {start = i;}}// Swap the starting point with the first pointint[] temp = trees[0];trees[0] = trees[start];trees[start] = temp;// Step 2: Sort the points based on polar angle with respect to the starting pointArrays.sort(trees, 1, trees.length, (a, b) -> {int orientation = orientation(trees[0], a, b);if (orientation == 0) {return distance(trees[0], a) - distance(trees[0], b); // Sort by distance if collinear}return orientation;});// Step 3 and 4: Graham scanList<int[]> hull = new ArrayList<>();for (int[] p : trees) {while (hull.size() >= 2 && orientation(hull.get(hull.size() - 2), hull.get(hull.size() - 1), p) > 0) {hull.remove(hull.size() - 1); // Remove the last point}hull.add(p);}// Convert the hull list to arrayreturn hull.toArray(new int[hull.size()][]);}// Helper function to calculate the cross product of vectors OA and OB// A positive cross product indicates a counter-clockwise turn, 0 indicates a collinear point, and negative indicates a clockwise turnprivate int orientation(int[] o, int[] a, int[] b) {return (a[1] - o[1]) * (b[0] - a[0]) - (a[0] - o[0]) * (b[1] - a[1]);}// Helper function to calculate the squared distance between two pointsprivate int distance(int[] a, int[] b) {return (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]);}
}
四、时间复杂度和空间复杂度
1. 时间复杂度
- 寻找起始点:O(n),其中n是数组
trees的长度。我们需要遍历所有点来找到y坐标最小(或x坐标最小,如果y坐标相同)的点。 - 排序点:O(n log n),使用快速排序或其他基于比较的排序算法对点进行排序,根据极角(如果极角相同,则根据距离)。
- Graham扫描:O(n),遍历排序后的点,对于每个点,我们可能需要从凸包中移除最后一个点,直到找到合适的点加入凸包。由于每个点最多被加入和移除一次,整个过程是线性的。
综上所述,总的时间复杂度是O(n log n),因为排序步骤是主导步骤。
2. 空间复杂度
- 凸包列表:O(n),在最坏的情况下,所有点都在凸包上,因此我们需要存储所有点。
- 辅助空间:O(1),除了凸包列表外,我们只使用了常数额外空间。
因此,总的空间复杂度是O(n),其中n是数组trees的长度。
五、总结知识点
-
算法设计:
- 凸包问题:理解凸包的概念以及如何通过算法找到给定点的凸包。
- Graham扫描算法:掌握Graham扫描算法的步骤,包括选择起始点、排序点、以及构建凸包。
-
数据结构:
- 数组:使用数组来存储点的坐标。
- 列表:使用
ArrayList来动态存储构成凸包的点。
-
排序:
- 自定义排序:使用
Arrays.sort方法和自定义比较器(Comparator)来根据极角和距离对点进行排序。
- 自定义排序:使用
-
数学概念:
- 向量叉乘:计算向量叉乘以确定点的相对位置(顺时针、逆时针或共线)。
- 距离计算:计算两点之间的欧几里得距离的平方,用于比较共线点之间的距离。
-
算法逻辑:
- 循环和条件判断:使用循环和条件判断来遍历点集,并在构建凸包时进行逻辑判断。
- 边界条件处理:检查点集长度,如果长度小于等于1,直接返回原点集。
-
辅助函数:
- 辅助函数
orientation:计算向量叉乘,用于判断点的相对位置。 - 辅助函数
distance:计算两点之间的距离的平方。
- 辅助函数
-
Java编程技巧:
- 数组操作:交换数组元素以将起始点置于数组首位。
- 泛型:使用泛型
ArrayList来存储int[]类型的点。 - Lambda表达式:在自定义排序中使用Lambda表达式简化代码。
以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。
相关文章:
LeetCode题练习与总结:安装栅栏--587
一、题目描述 给定一个数组 trees,其中 trees[i] [xi, yi] 表示树在花园中的位置。 你被要求用最短长度的绳子把整个花园围起来,因为绳子很贵。只有把 所有的树都围起来,花园才围得很好。 返回恰好位于围栏周边的树木的坐标。 示例 1: 输…...
< OS 有关 > 阿里云 几个小时前 使用密钥替换 SSH 密码认证后, 发现主机正在被“攻击” 分析与应对
信息来源: 文件:/var/log/auth.log 因为在 sshd_config 配置文件中,已经定义 LogLevel INFO 部分内容: 2025-01-27T18:18:55.68272708:00 jpn sshd[15891]: Received disconnect from 45.194.37.171 port 58954:11: Bye Bye […...
使用八爪鱼爬虫和Web Scraper抓取数据实战案例,附详细教程
最近有不少小伙伴咨询怎么抓取抖音视频或者评论的数据,他们多是自媒体或者商家,想要模仿爆火视频或者分析视频评论区的舆情信息,确实呀,现在抖音是流量高地,淘金的地方,真的是一个值得挖掘的宝藏。当然我一…...
海外问卷调查渠道查如何设置:最佳实践+示例
随着经济全球化和一体化进程的加速,企业间的竞争日益加剧,为了获得更大的市场份额,对企业和品牌而言,了解受众群体的的需求、偏好和痛点才是走向成功的关键。而海外问卷调查才是获得受众群体痛点的关键,制作海外问卷调…...
【C++数论】880. 索引处的解码字符串|2010
本文涉及知识点 数论:质数、最大公约数、菲蜀定理 LeetCode880. 索引处的解码字符串 给定一个编码字符串 s 。请你找出 解码字符串 并将其写入磁带。解码时,从编码字符串中 每次读取一个字符 ,并采取以下步骤: 如果所读的字符是…...
从ai产品推荐到利用cursor快速掌握一个开源项目再到langchain手搓一个Text2Sql agent
目录 0. 经验分享:产品推荐 1. 经验分享:提示词优化 2. 经验分享:使用cursor 阅读一篇文章 3. 经验分享:使用cursor 阅读一个完全陌生的开源项目 4. 经验分享:手搓一个text2sql agent (使用langchain l…...
freeswitch在centos上编译过程
操作系统:centos9-last usr/local/freeswitch/bin/freeswitch -version FreeSWITCH version: 1.10.13-devgit~20250125T131725Z~3f1e4bf90a~64bit (git 3f1e4bf 2025-01-25 13:17:25Z 64bit)vi /etc/ssh/sshd_config ip a nmtui reboot ip a curl -o /etc/pki/rpm-…...
项目测试之MockMvc
文章目录 基础基础概念Mockxxx一般实现文件位置 实战MockMvc与Test注解不兼容RequestParams参数RequestBody参数 基础 基础概念 定义:是Spring框架提供的一种用于测试Spring MVC控制器的工具,它允许开发者在不启动完整的web服务器的情况下,…...
Blazor-选择循环语句
今天我们来说说Blazor选择语句和循环语句。 下面我们以一个简单的例子来讲解相关的语法,我已经创建好了一个Student类,以此类来进行语法的运用 因为我们需要交互性所以我们将类创建在*.client目录下 if 我们做一个学生信息的显示,Gender为…...
【第一天】零基础入门刷题Python-算法篇-数据结构与算法的介绍(持续更新)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、Python数据结构与算法的详细介绍1.基本概念2.Python中的数据结构1. 列表(List)2. 元组(Tuple)3. 字典&#…...
appium自动化环境搭建
一、appium介绍 appium介绍 appium是一个开源工具、支持跨平台、用于自动化ios、安卓手机和windows桌面平台上面的原生、移动web和混合应用,支持多种编程语言(python,java,Ruby,Javascript、PHP等) 原生应用和混合应用…...
大数据Hadoop入门2
目录 第三部分(Hadoop MapReduce和Hadoop YARN) 1.课程内容-大纲-学习目标 2.理解先分再合、分而治之的思想 3.hadoop团队针对MapReduce的设计构思 4.Hadoop MapReduce介绍、阶级划分和进程组成 5.Hadoop MapReduce官方示例-圆周率PI评估 6.Hadoo…...
21.Word:小赵-毕业论文排版❗【39】
目录 题目 NO1.2 NO3.4 NO5.6 NO7.8.9 NO10.11.12 题目 NO1.2 自己的论文当中接收老师的修改:审阅→比较→源文档:考生文件夹:Word.docx→修订的文档:考生文件夹:教师修改→确定→接收→接收所有修订将合并之…...
【go语言】并发编程
一、协程、线程、进程 在计算机编程中,进程、线程和协程都是用于并发执行任务的不同概念。他们的区别主要体现在创建、管理和调度的复杂度上,特别是在不同的编程语言中有不同的实现方式。下面是他们的详细区别和在 go 语言中的实现方式。 1.1 进程 定义…...
算法1-1 模拟与高精度
目录 一 阶乘数码 二 麦森数 三 模拟题 一 阶乘数码 本题中n<1000,1000的阶乘为以下这么大,远超long的范围 402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901…...
JS中对数组的操作哪些会改变原数组哪些不会?今天你一定要记下!
JavaScript 数组方法:变更原数组与不变更原数组的区别 在 JavaScript 中,数组是非常常见且重要的数据结构。作为开发者,我们常常需要使用数组方法来处理数组数据。但是,数组的不同方法会以不同的方式影响原数组,它们可…...
公式与函数的应用
一 相邻表格相乘 1 也可以复制 打印标题...
ShenNiusModularity项目源码学习(7:数据库结构)
ShenNiusModularity项目默认使用mysql数据库,数据库连接字符串放到了ShenNius.Admin. Mvc、ShenNius.Admin.Hosting的appsettings.json文件内。 ShenNiusModularity项目为自媒体内容管理系统,支持常规管理、CMS管理、商城管理等功能,其数…...
【STL笔记】字符串
字符串 下标从0开始,常规用法不再赘述,持续更新中… 1. substr(pos,len): 返回从位置 pos 开始,长度为 len 的子串。(len默认为npos) std::string str "Hello, World!"; std::string sub1 str.substr(7, 5); // 提…...
java知识点 | java中不同数据结构的长度计算
在Java中,size 和 length是两个不同的属性,分别用于不同的数据结构。以下是它们的详细区别和适用场景: 1.length 适用对象: 数组(Array):数组是一个固定长度的线性数据结构,其长度是…...
WordPress event-monster插件存在信息泄露漏洞(CVE-2024-11396)
免责声明: 本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在…...
手撕Diffusion系列 - 第九期 - 改进为Stable Diffusion(原理介绍)
手撕Diffusion系列 - 第九期 - 改进为Stable Diffusion(原理介绍) 目录 手撕Diffusion系列 - 第九期 - 改进为Stable Diffusion(原理介绍)DDPM 原理图Stable Diffusion 原理Stable Diffusion的原理解释Stable Diffusion 和 Diffus…...
AI软件栈:LLVM分析(一)
文章目录 AI 软件栈后端编译LLVM IRLLVM的相关子项目AI 软件栈后端编译 AI软件栈的后端工作通常与硬件架构直接相关,为了实现一个既能适配现代编程语言、硬件架构发展的目标,所以提出了LLVM具备多阶段优化能力提供基础后端描述,便于进行编译器开发兼容标准编译器的行为LLVM …...
编程语言中的常见Bug及解决方案
在编程过程中,不同语言有其独特的特性和挑战,这也导致了各种常见Bug的出现。本文将总结几种主流编程语言中的常见Bug,包括JavaScript、Python、C/C、Java和Go,并提供相应的解决方案和案例。 一、JavaScript中小数相加精度不准确的…...
论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(三)
Understanding Diffusion Models: A Unified Perspective(三) 文章概括 文章概括 引用: article{luo2022understanding,title{Understanding diffusion models: A unified perspective},author{Luo, Calvin},journal{arXiv preprint arXiv:…...
修改maven的编码格式为utf-8
1.maven默认编码为GBK 注:配好MAVEN_HOME的环境变量后,在运行cmd. 打开cmd 运行mvn -v命令即可. 2.修改UTF-8为默认编码. 设置环境变量 变量名 MAVEN_OPTS 变量值 -Xms256m -Xmx512m -Dfile.encodingUTF-8 3.保存,退出cmd.重新打开cmd 运行mvn -v命令即可. 源码获取&…...
从AD的原理图自动提取引脚网络的小工具
这里跟大家分享一个我自己写的小软件,实现从AD的原理图里自动找出网络名称和引脚的对应。存成文本方便后续做表格或是使用简单行列编辑生成引脚约束文件(如.XDC .UCF .TCL等)。 我们在FPGA设计中需要引脚锁定文件,就是指示TOP层…...
Coze,Dify,FastGPT,对比
在当今 AI 技术迅速发展的背景下,AI Agent 智能体成为了关键领域,Coze、Dify 和 FastGPT 作为其中的佼佼者,各有千秋。 平台介绍 - FastGPT:由环界云计算公司发起,是基于大语言模型(LLM)的开源…...
【数据结构】_链表经典算法OJ(力扣版)
目录 1. 移除链表元素 1.1 题目描述及链接 1.2 解题思路 1.3 程序 2. 反转链表 2.1 题目描述及链接 2.2 解题思路 2.3 程序 3. 链表的中间结点 3.1 题目描述及链接 3.2 解题思路 3.3 程序 1. 移除链表元素 1.1 题目描述及链接 原题链接:203. 移除链表…...
【数据结构】(1)集合类的认识
一、什么是数据结构 1、数据结构的定义 数据结构就是存储、组织数据的方式,即相互之间存在一种或多种关系的数据元素的集合。 2、学习数据结构的目的 在实际开发中,我们需要使用大量的数据。为了高效地管理这些数据,实现增删改查等操作&…...
