You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

56 lines
1.6 KiB

2 years ago
package class50;
import java.util.Arrays;
public class Problem_0587_ErectTheFence {
public static int[][] outerTrees(int[][] points) {
int n = points.length;
int s = 0;
int[][] stack = new int[n << 1][];
// x小的排前面x一样的y小的排前面
Arrays.sort(points, (a, b) -> a[0] != b[0] ? a[0] - b[0] : a[1] - b[1]);
for (int i = 0; i < n; i++) {
while (s > 1 && cross(stack[s - 2], stack[s - 1], points[i]) > 0) {
s--;
}
stack[s++] = points[i];
}
for (int i = n - 2; i >= 0; i--) {
while (s > 1 && cross(stack[s - 2], stack[s - 1], points[i]) > 0) {
s--;
}
stack[s++] = points[i];
}
// 去重返回
Arrays.sort(stack, 0, s, (a, b) -> b[0] == a[0] ? b[1] - a[1] : b[0] - a[0]);
n = 1;
for (int i = 1; i < s; i++) {
// 如果i点x和y与i-1点x和y都一样
// i点与i-1点在同一个位置此时i点不保留
if (stack[i][0] != stack[i - 1][0] || stack[i][1] != stack[i - 1][1]) {
stack[n++] = stack[i];
}
}
return Arrays.copyOf(stack, n);
}
// 叉乘的实现
// 假设有a、b、c三个点并且给出每个点的(x,y)位置
// 从a到c的向量在从a到b的向量的哪一侧
// 如果a到c的向量在从a到b的向量右侧返回正数
// 如果a到c的向量在从a到b的向量左侧返回负数
// 如果a到c的向量和从a到b的向量重合返回0
public static int cross(int[] a, int[] b, int[] c) {
return (b[1] - a[1]) * (c[0] - b[0]) - (b[0] - a[0]) * (c[1] - b[1]);
}
public static void main(String[] args) {
int[] a = { 4, 4 };
int[] b = { 1, 1 };
int[] c = { 1, 5 };
System.out.println(cross(a, b, c));
}
}