题目链接

安装栅栏

题目描述

image.png

解题思路

方法一: Jarvis 算法

image.png
这里需要注意:r是在向量pq的左边,而不是上下边的概念image.png
image.png
实现代码:

  1. class Solution {
  2. public int[][] outerTrees(int[][] trees) {
  3. int n = trees.length;
  4. if (n < 4) {
  5. return trees;
  6. }
  7. int leftMost = 0;
  8. for (int i = 0; i < n; i++) {
  9. if (trees[i][0] < trees[leftMost][0]) {
  10. leftMost = i;
  11. }
  12. }
  13. List<int[]> res = new ArrayList<int[]>();
  14. boolean[] visit = new boolean[n];
  15. int p = leftMost;
  16. do {
  17. int q = (p + 1) % n;
  18. for (int r = 0; r < n; r++) {
  19. /* 如果 r 在 pq 的右侧,则 q = r */
  20. if (cross(trees[p], trees[q], trees[r]) < 0) {
  21. q = r;
  22. }
  23. }
  24. /* 是否存在点 i, 使得 p 、q 、i 在同一条直线上 */
  25. for (int i = 0; i < n; i++) {
  26. if (visit[i] || i == p || i == q) {
  27. continue;
  28. }
  29. if (cross(trees[p], trees[q], trees[i]) == 0) {
  30. res.add(trees[i]);
  31. visit[i] = true;
  32. }
  33. }
  34. if (!visit[q]) {
  35. res.add(trees[q]);
  36. visit[q] = true;
  37. }
  38. p = q;
  39. } while (p != leftMost);
  40. return res.toArray(new int[][]{});
  41. }
  42. public int cross(int[] p, int[] q, int[] r) {
  43. return (q[0] - p[0]) * (r[1] - q[1]) - (q[1] - p[1]) * (r[0] - q[0]);
  44. }
  45. }