一、题目描述
You have a list of points in the plane.
Return the area of the largest triangle that can be formed by any 3 of the points.
Example:
Input: points =
[
[0,0],
[0,1],
[1,0],
[0,2],
[2,0]]
Output: 2
Explanation:
The five points are show in the figure below. The red triangle is the largest.
Notes:
3 <= points.length <= 50.
No points will be duplicated.
-50 <= points[i][j] <= 50.
Answers within 10^-6 of the true value will be accepted as correct.
二、题解
三种计算面积的公式
- 鞋带公式,用于计算任意多边形的面积,可用于计算三角形的面积;
- 海伦公式,从三个顶点得到三边长,并使用海伦公司计算出面积;
p = (a+b+c) / 2
s = 根号 p(p-a)(p-b)(p-c) - 三角形面积公式 S = 1/2absin©,首先得到两边的长度,通过叉积算出夹角的正弦值,并使用公式计算出面积。
(1) 鞋带公式
三层循环找出三个点,每次更新一个点的数值。当三个点A、B、C的坐标分别为A(x1,y1)、B(x2,y2)、C(x3、y3)时,三角形面积为 S=(x1y2-x1y3+x2y3-x2y1+x3y1-x2y2)。
证明
设三个点A、B、C的坐标分别为A(x1,y1)、B(x2,y2)、C(x3、y3)
那么 A、B、C 三点可围成一个三角形。AC 与 AB 边的夹角为 ∠A。
那么向量AB=(x2-x1,y2-y1)、向量AC=(x3-x1,y3-y1)。
令向量AB=a,向量AC=b,
则根据向量运算法则可得,|a·b|=|a|·|b|·|cosA|, 那么 cosA=|a·b|/(|a|·|b|),则 sinA=√((|a|·|b|)2-(|a·b|)2)/(|a|·|b|)。
那么三角形的面积 S=|a|·|b|·sinA=√((|a|·|b|)2-(|a·b|)2),又a·b=(x2-x1)(x3-x1)+(y2-y1)(y3-y1),
那么可得三角形的面积 S=(x1y2 - x1y3 + x2y3 - x2y1 + x3y1 - x2y2)1/2。即
(x1y2 - x2y1 + x2y3 - x3y2 + x3y1 - x1y3) / 2
/**
* 执行用时 5 ms 击败了 85.56 % 的java用户
*/
public double largestTriangleArea2(int[][] points) {
int N = points.length;
double largeArea=0;
for (int i = 0; i < N-2; i++) {
int x1 = points[i][0];
int y1 = points[i][1];
for (int j = i+1; j < N-1; j++) {
int x2 = points[j][0];
int y2 = points[j][1];
for (int k = j+1; k < N; k++) {
int x3 = points[k][0];
int y3 = points[k][1];
double tS = 0.5*Math.abs((x1*y2 - x2*y1 + x2*y3 - x3*y2 + x3*y1 - x1*y3));
// 为什么不能用 >>1 / >>>1
if(tS > largeArea)
largeArea = tS;
}
}
}
return largeArea;
复杂度分析
- 时间复杂度:
- 空间复杂度: