首页/新闻资讯/正文详情

LeetCode 587题解析:Andrew算法实现二维凸包计算

发布时间:2026/11/5 10:38:18 来源:云帆数科 栏目:资讯中心
LeetCode 587题解析:Andrew算法实现二维凸包计算
1. 问题背景与需求分析LeetCode 587题安装栅栏是一个经典的计算几何问题要求我们找到一组二维平面点的最小凸包。这个问题在实际中有很多应用场景比如农场主需要围住所有树木的最小围栏长度军事上部署雷达站的最小覆盖范围城市规划中确定建筑群的外边界给定一组树的坐标trees[i] [xi, yi]我们需要返回构成凸包的树的位置。凸包的定义是包含所有点的最小凸多边形其中凸多边形是指多边形内部任意两点连线都在多边形内部。2. 凸包算法选型与比较解决凸包问题有几种常见算法我们需要先了解它们的优缺点2.1 Graham扫描法时间复杂度O(nlogn)需要先找到一个基点然后按极角排序最后用栈维护凸包。优点是效率高但实现相对复杂。2.2 Jarvis步进法礼品包装算法时间复杂度O(nh)其中h是凸包上的点数。从最左边的点开始逐步包裹所有点。实现简单但最坏情况下效率低。2.3 Andrew算法这是本问题推荐的方法可以看作是Graham扫描的改进版将所有点按x坐标排序x相同则按y分别构建下凸包和上凸包合并两部分得到完整凸包时间复杂度O(nlogn)实现相对简单且效率稳定。3. Andrew算法实现详解以下是使用Andrew算法解决该问题的Java实现public int[][] outerTrees(int[][] trees) { if (trees.length 3) return trees; // 按x升序排序x相同则按y升序 Arrays.sort(trees, (a, b) - { if (a[0] b[0]) return a[1] - b[1]; return a[0] - b[0]; }); Listint[] hull new ArrayList(); // 构建下凸包 for (int[] tree : trees) { while (hull.size() 2 cross(hull.get(hull.size()-2), hull.get(hull.size()-1), tree) 0) { hull.remove(hull.size()-1); } hull.add(tree); } // 构建上凸包 for (int i trees.length-1; i 0; i--) { while (hull.size() 2 cross(hull.get(hull.size()-2), hull.get(hull.size()-1), trees[i]) 0) { hull.remove(hull.size()-1); } hull.add(trees[i]); } // 去除重复点 HashSetint[] set new HashSet(hull); return set.toArray(new int[set.size()][]); } // 计算向量叉积 private int cross(int[] a, int[] b, int[] c) { return (b[0]-a[0])*(c[1]-b[1]) - (b[1]-a[1])*(c[0]-b[0]); }4. 关键代码解析4.1 叉积计算cross函数计算的是向量ab和向量bc的叉积结果0点c在向量ab的左侧结果0点c在向量ab的右侧结果0三点共线这是判断点是否在凸包上的核心数学工具。4.2 凸包构建过程下凸包构建时我们从左向右处理点每次尝试将当前点加入凸包如果新点导致凸包凹陷叉积0就移除前一个点直到满足凸性条件上凸包构建同理只是从右向左处理。4.3 边界情况处理点数≤3时直接返回因为3个点必然形成凸包最后使用HashSet去重因为起点会被两次加入5. 测试用例与验证验证算法正确性需要设计多种测试场景// 常规情况 int[][] test1 {{1,1},{2,2},{2,0},{2,4},{3,3},{4,2}}; // 所有点共线 int[][] test2 {{1,1},{2,2},{3,3},{4,4}}; // 矩形分布 int[][] test3 {{0,0},{0,4},{4,0},{4,4},{2,2}}; // 重复点 int[][] test4 {{1,1},{1,1},{1,1}};对于共线点的情况Andrew算法会将它们全部包含在凸包中这是题目要求的。实际应用中可能需要根据需求调整。6. 算法优化与变种6.1 处理共线点如果希望凸包只包含端点可以修改判断条件// 将 0 改为 0 cross(hull.get(hull.size()-2), hull.get(hull.size()-1), tree) 06.2 性能优化对于大规模数据使用快速排序替代Arrays.sort预分配List大小减少扩容开销对于已知分布的数据可以采用分治策略6.3 三维凸包扩展虽然本题是二维的但算法可以扩展到三维空间使用类似的思想处理面而不是边。7. 实际应用中的注意事项浮点精度问题实际工程中坐标可能是浮点数直接使用叉积判断时要注意精度误差可以设置一个很小的epsilon值。退化情况所有点共线或重合时要有特殊处理避免算法陷入死循环。内存管理对于极大点数要注意Java的自动装箱和GC影响可以考虑使用原生数组。并行化可能排序阶段和上下凸包构建可以并行处理但要注意线程安全。我在实际项目中遇到过一个问题当点数超过10万时默认的排序方法会成为瓶颈。解决方案是改用基于基数排序的方法将时间复杂度从O(nlogn)降到O(n)。

相关推荐

车联网低延迟通信仿真与5G URLLC优化实践
车联网低延迟通信仿真与5G URLLC优化实践

1. 车联网低延迟通信仿真需求背景车联网(V2X)通信作为智能交通系统的核心技术,正在彻底改变车辆与周围环境交互的方式。在紧急制动预警、交叉路口碰撞避免等关键场景中,端到端通信延迟必须控制在10毫秒以内,这对通信系… · 2026/11/5 7:56:26

Materials Studio 2020 Linux部署实战:CentOS/Ubuntu/Rocky环境配置与避坑指南
Materials Studio 2020 Linux部署实战:CentOS/Ubuntu/Rocky环境配置与避坑指南

1. 为什么要在Linux上折腾材料计算软件做材料模拟这行的朋友大概都有体会,Materials Studio这套工具在Windows下用起来确实顺手,图形界面点一点、参数填一填就能跑起来。但真正要把计算任务铺开、要跑几百上千个结构优化或者能带计算的时候,W… · 2026/11/5 10:28:53

LR-FHSS技术解析:卫星物联网通信的关键突破
LR-FHSS技术解析:卫星物联网通信的关键突破

1. 项目背景与核心价值去年参与某农业物联网项目时,第一次接触到LR-FHSS技术。当时农户需要在方圆50公里的山地监测土壤墒情,传统LoRa网关部署成本高得惊人。正是这次经历让我意识到:直达卫星的LPWAN通信,可能是解决广域物联网覆盖… · 2026/11/5 1:49:23

实验室冰箱监控系统优化:快速定位与参数追溯方案
实验室冰箱监控系统优化:快速定位与参数追溯方案

1. 问题场景解析:实验室冰箱监控的痛点与需求在生物医药、食品检测等实验室环境中,样本存储冰箱的温度稳定性直接关系到样本质量。当监控系统触发异常报警时,技术人员常面临两个核心问题:一是无法快速定位具体设备,二是… · 2026/11/6 2:34:55

26天打卡习惯养成:从行为设计到神经机制
26天打卡习惯养成:从行为设计到神经机制

1. 打卡机制的本质与价值连续打卡26天这个行为背后,隐藏着一套完整的习惯养成方法论。从行为心理学角度看,打卡本质上是一种"承诺机制"(Commitment Device),通过外在形式强化内在动机。我曾在团队管理中推行… · 2026/11/6 2:34:55

基于AT89C52与DS18B20的单总线数字温度计工程实战
基于AT89C52与DS18B20的单总线数字温度计工程实战

简介:本资源是一份面向电子信息类本科生及单片机初学者的毕业论文文档,聚焦基于AT89C52单片机与DS18B20传感器的数字温度计系统设计,解决传统热电偶/热电阻测温电路复杂、需多级信号调理的问题。全文涵盖引言、Proteus与Keil开发环境介绍、系… · 2026/11/6 2:34:55

2026网络安全自学路线:零基础到进阶实战指南
2026网络安全自学路线:零基础到进阶实战指南

1. 网络安全自学路线图概述第一次接触网络安全的新手常会陷入迷茫——该从哪开始学?需要掌握哪些技能?市面上资料太多反而无从下手。这份2026版自学路线图是我根据八年行业经验总结的体系化学习框架,从零基础到进阶实战全覆盖,帮你… · 2026/11/6 2:34:55

PostgreSQL UPSERT机制深度解析与最佳实践
PostgreSQL UPSERT机制深度解析与最佳实践

1. 项目概述:PostgreSQL的UPSERT革命PostgreSQL 9.5版本引入的INSERT ON CONFLICT语法(俗称UPSERT)彻底改变了开发者在处理数据冲突时的编程范式。这个功能允许我们在单条SQL语句中实现"存在则更新,不存在则插入"的逻辑… · 2026/11/6 2:34:55

Nginx代理Redis:安全与性能优化实践
Nginx代理Redis:安全与性能优化实践

1. 为什么需要Nginx代理Redis?Redis作为高性能的内存数据库,通常直接暴露在应用服务器之间进行通信。但在实际生产环境中,这种直连方式会带来几个明显问题:首先是安全性隐患。Redis默认没有完善的认证机制,如果直接将6… · 2026/11/6 2:33:55

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:27:59

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:03

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:07

三菱PLC数据采集到数据库的时序设计:Python+MC协议实战
三菱PLC数据采集到数据库的时序设计:Python+MC协议实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 1:02:11

ASIC主模式RTL设计:状态机与三态驱动的流片级实现
ASIC主模式RTL设计:状态机与三态驱动的流片级实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 1:02:11

STM32嵌入式C++开发:GDB调试与Renode仿真实战指南
STM32嵌入式C++开发:GDB调试与Renode仿真实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/6 1:02:11

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:27:59

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:03

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:07

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码