0812-最大三角形面积
给你一个由 X-Y 平面上的点组成的数组 points
,其中 points[i] = [xi, yi]
。从其中取任意三个不同的点组成三角形,返回能组成的最大三角形的面积。与真实值误差在 10-5
内的答案将会视为正确答案 。
示例 1:
**输入:** points = [[0,0],[0,1],[1,0],[0,2],[2,0]]
**输出:** 2.00000
**解释:** 输入中的 5 个点如上图所示,红色的三角形面积最大。
示例 2:
**输入:** points = [[1,0],[0,0],[0,1]]
**输出:** 0.50000
提示:
3 <= points.length <= 50
-50 <= xi, yi <= 50
- 给出的所有点 互不相同
方法一:枚举
思路与算法
关于求解三角形面积的公式可以参考百度百科「三角形面积公式 」。
我们可以枚举所有的三角形,然后计算三角形的面积并找出最大的三角形面积。设三角形三个顶点的坐标为 (x_1, y_1)、(x_2, y_2) 和 (x_3, y_3),则三角形面积 S 可以用行列式的绝对值表示:
S = 1/2} \left| \begin{vmatrix} x_1 & y_1 & 1 \ x_2 & y_2 & 1 \ x_3 & y_3 &1 \end{vmatrix} \right| = 1/2} \lvert x_1 y_2 + x_2 y_3 + x_3 y_1 - x_1 y_3 - x_2 y_1 - x_3 y_2 \rvert
代码
1 | class Solution: |
1 | class Solution { |
1 | class Solution { |
1 | public class Solution { |
1 | static inline double max(double a, double b) { |
1 | var largestTriangleArea = function(points) { |
1 | func triangleArea(x1, y1, x2, y2, x3, y3 int) float64 { |
复杂度分析
时间复杂度:O(n^3),其中 n 是数组 points 的长度。三重循环需要 O(n^3)。
空间复杂度:O(1)。
方法二:凸包
思路与算法
我们先使用 Andrew 算法求出所有点对应的凸包 convexHull,参考官方题解「587. 安装栅栏 」的凸包算法。
如果三角形的某一点不在凸包上,我们以其余两点的边为底,那么我们总可以在凸包上找到一个点,使得该点到此边的高大于原来的点到此边的高,因此面积最大的三角形的三个点都在凸包上。
在凸包 convexHull 上枚举三角形,先枚举点 i,然后枚举点 j,最后枚举点 k,其中 i \lt j \lt k。
在固定点 i 和 j 后,三角形的面积与 k 的关系是一个凸曲线,因此三角形只在 k 为极点时面积最大。在固定点 i 时,该极点在随点 j 增大而增大,因此在搜索极点只需要从上次的极点位置开始搜索。
所以我们不需要枚举点 k,只需要搜索点 i 和 j 对应的极点,然后求解三角形面积。返回最大的三角形面积。
代码
1 | class Solution: |
1 | class Solution { |
1 | class Solution { |
1 | public class Solution { |
1 |
|
1 | func cross(p, q, r []int) int { |
1 | var largestTriangleArea = function(points) { |
复杂度分析
时间复杂度:O(n^2),其中 n 是数组 points 的长度。Andrew 算法的时间复杂度为 O(n \log n),在凸包上枚举三角形的时间复杂度为 O(n^2)。
空间复杂度:O(n)。Andrew 算法的空间复杂度为 O(n),保存凸包需要 O(n) 的空间。