当前位置: 首页 > news >正文

凸包法解算法题——最大三角形面积

思路与算法我们先使用 Andrew 算法求出所有点对应的凸包 convexHull。如果三角形的某一点不在凸包上我们以其余两点的边为底那么我们总可以在凸包上找到一个点使得该点到此边的高大于原来的点到此边的高因此面积最大的三角形的三个点都在凸包上。在凸包 convexHull 上枚举三角形先枚举点 i然后枚举点 j最后枚举点 k其中 ijk。在固定点 i 和 j 后三角形的面积与 k 的关系是一个凸曲线因此三角形只在 k 为极点时面积最大。在固定点 i 时该极点在随点 j 增大而增大因此在搜索极点只需要从上次的极点位置开始搜索。所以我们不需要枚举点 k只需要搜索点 i 和 j 对应的极点然后求解三角形面积。返回最大的三角形面积。代码Python3class Solution: def getConvexHull(self, points: List[List[int]]) - List[List[int]]: def cross(p: List[int], q: List[int], r: List[int]) - int: return (q[0] - p[0]) * (r[1] - q[1]) - (q[1] - p[1]) * (r[0] - q[0]) n len(points) if n 4: return points # 按照 x 从小到大排序如果 x 相同则按照 y 从小到大排序 points.sort() hull [] # 求凸包的下半部分 for i, p in enumerate(points): while len(hull) 1 and cross(hull[-2], hull[-1], p) 0: hull.pop() hull.append(p) # 求凸包的上半部分 m len(hull) for i in range(n - 2, -1, -1): while len(hull) m and cross(hull[-2], hull[-1], points[i]) 0: hull.pop() hull.append(points[i]) hull.pop() # hull[0] 同时参与凸包的上半部分检测因此需去掉重复的 hull[0] return hull def largestTriangleArea(self, points: List[List[int]]) - float: def triangleArea(x1: int, y1: int, x2: int, y2: int, x3: int, y3: int) - float: return abs(x1 * y2 x2 * y3 x3 * y1 - x1 * y3 - x2 * y1 - x3 * y2) / 2 convexHull self.getConvexHull(points) ans, n 0, len(convexHull) for i, p in enumerate(convexHull): k i 2 for j in range(i 1, n - 1): q convexHull[j] while k 1 n: curArea triangleArea(p[0], p[1], q[0], q[1], convexHull[k][0], convexHull[k][1]) nextArea triangleArea(p[0], p[1], q[0], q[1], convexHull[k 1][0], convexHull[k 1][1]) if curArea nextArea: break k 1 ans max(ans, triangleArea(p[0], p[1], q[0], q[1], convexHull[k][0], convexHull[k][1])) return ansJavaclass Solution { public double largestTriangleArea(int[][] points) { int[][] convexHull getConvexHull(points); int n convexHull.length; double ret 0.0; for (int i 0; i n; i) { for (int j i 1, k i 2; j 1 n; j) { while (k 1 n) { double curArea triangleArea(convexHull[i][0], convexHull[i][1], convexHull[j][0], convexHull[j][1], convexHull[k][0], convexHull[k][1]); double nextArea triangleArea(convexHull[i][0], convexHull[i][1], convexHull[j][0], convexHull[j][1], convexHull[k 1][0], convexHull[k 1][1]); if (curArea nextArea) { break; } k; } double area triangleArea(convexHull[i][0], convexHull[i][1], convexHull[j][0], convexHull[j][1], convexHull[k][0], convexHull[k][1]); ret Math.max(ret, area); } } return ret; } public int[][] getConvexHull(int[][] points) { int n points.length; if (n 4) { return points; } /* 按照 x 大小进行排序如果 x 相同则按照 y 的大小进行排序 */ Arrays.sort(points, (a, b) - { if (a[0] b[0]) { return a[1] - b[1]; } return a[0] - b[0]; }); Listint[] hull new ArrayListint[](); /* 求出凸包的下半部分 */ for (int i 0; i n; i) { while (hull.size() 1 cross(hull.get(hull.size() - 2), hull.get(hull.size() - 1), points[i]) 0) { hull.remove(hull.size() - 1); } hull.add(points[i]); } int m hull.size(); /* 求出凸包的上半部分 */ for (int i n - 2; i 0; i--) { while (hull.size() m cross(hull.get(hull.size() - 2), hull.get(hull.size() - 1), points[i]) 0) { hull.remove(hull.size() - 1); } hull.add(points[i]); } /* hull[0] 同时参与凸包的上半部分检测因此需去掉重复的 hull[0] */ hull.remove(hull.size() - 1); m hull.size(); int[][] hullArr new int[m][]; for (int i 0; i m; i) { hullArr[i] hull.get(i); } return hullArr; } public double triangleArea(int x1, int y1, int x2, int y2, int x3, int y3) { return 0.5 * Math.abs(x1 * y2 x2 * y3 x3 * y1 - x1 * y3 - x2 * y1 - x3 * y2); } public int cross(int[] p, int[] q, int[] r) { return (q[0] - p[0]) * (r[1] - q[1]) - (q[1] - p[1]) * (r[0] - q[0]); } }
http://www.rkmt.cn/news/1405033.html

相关文章:

  • python学习-xx14-1 pandas【⭐】
  • 在模型频繁更新时代Taotoken提供的最新模型接入体验
  • 大气网格化监测气象站:一张网管住城市空气质量
  • Page Assist完整指南:浏览器侧边栏本地AI助手终极教程
  • 【AI时代绩效革命】:首次公开——ChatGPT岗位胜任力雷达图(含6项硬指标+3项灰度阈值)
  • Windows终极定制神器:Windhawk让系统完全按你的想法工作
  • 数据异构下联邦学习的拜占庭攻防:挑战、机制与评估
  • 为开源AI工具OpenClaw配置Taotoken作为模型供应商的指南
  • 2026 卫生型液体流量计(卡箍/卡盘)厂家一览:国产与进口流量计怎么选?卡箍/卡盘电磁流量计品牌选型 - 流量计品牌
  • FPGA近似计算设计空间探索:模型驱动与输入感知方法对比与实践
  • 为AI智能体构建可信工具搜索引擎:从意图理解到动态信任评估
  • 虚拟化- x86 频率调节方法
  • ESP32智能车牌识别系统:如何在嵌入式设备上实现边缘AI视觉处理?
  • ESP32视觉处理:从边缘计算到智能图像分析的技术演进
  • 基于容器编排的企业级IPAM和DCIM基础设施管理平台部署指南
  • 如何用LeagueAkari让你的英雄联盟游戏体验提升300%:一站式客户端工具箱完全指南
  • Zepp Life步数自动化同步:完整指南与深度技术解析
  • Window Resizer终极指南:3分钟掌握Windows窗口尺寸自由调整技巧
  • 经典算法题型之最大三角形面积(二)
  • 3步实现微信聊天记录永久保存:开源工具WeChatMsg完全指南
  • 鸣潮自动化助手ok-ww:让重复操作成为过去式的智能伴侣
  • ABAP Excel样式进阶:从单元格格式到专业报表美化的实战指南
  • 解决Claude Code访问不稳定问题并实现无缝对接Taotoken
  • 3个高效优化Windows系统的专业技巧:AtlasOS完整配置秘籍
  • OpCore-Simplify终极指南:让黑苹果配置像安装Windows一样简单
  • TypeScript 编程:交叉类型(Intersection Types)与类型合并冲突解析
  • 从“看得到AI,落不了地”到真正可用:食品包装审核的真实痛点
  • TypeScript编程进阶:联合类型与类型保护详解
  • C# ToCharArray + foreach遍历 + String与StringBuilder
  • GHelper:华硕笔记本轻量级控制工具,3分钟提升系统性能与续航