https://leetcode-cn.com/problems/the-skyline-problem/
这道题跟摩天大楼类似

有序表

image.png

image.png
image.png
接下来根据第一个值进行排序
image.png

然后搞一个有序表,key就是高度, value就是这个高度出现的次数,
一个map,key是位置,value是这个位置的最大高度
只要最大高度有波动,它就是一个轮廓线产生的位置
image.png
image.png
image.png
image.png
image.png
image.png
所以答案就是拐点
image.png

ps注意:要防止纸片楼
image.png
在7位置加然后又在7位置减, 在比较器中就需要让加排在前面,减排在后面

  1. public static class Node {
  2. public int x;
  3. public boolean isAdd;
  4. public int h;
  5. public Node(int x, boolean isAdd, int h) {
  6. this.x = x;
  7. this.isAdd = isAdd;
  8. this.h = h;
  9. }
  10. }
  11. public static class NodeComparator implements Comparator<Node> {
  12. @Override
  13. public int compare(Node o1, Node o2) {
  14. if (o1.x != o2.x) {
  15. return o1.x - o2.x;
  16. }
  17. if (o1.isAdd != o2.isAdd) {
  18. return o1.isAdd ? -1 : 1;
  19. }
  20. return 0;
  21. }
  22. }
  23. public List<List<Integer>> getSkyline(int[][] buildings) {
  24. Node[] nodes = new Node[buildings.length * 2];
  25. for (int i = 0; i < buildings.length; i++) {
  26. nodes[i * 2] = new Node(buildings[i][0], true, buildings[i][2]);
  27. nodes[i * 2 + 1] = new Node(buildings[i][1], false, buildings[i][2]);
  28. }
  29. Arrays.sort(nodes, new NodeComparator());
  30. // 有序表,key 代表某个高度 value 这个高度出现的次数
  31. TreeMap<Integer, Integer> mapHeightTimes = new TreeMap<>();
  32. // 有序表 key x的值 value 处在x位置时的高度
  33. TreeMap<Integer, Integer> xMaxHeight = new TreeMap<>();
  34. for (int i = 0; i < nodes.length; i++) {
  35. if (nodes[i].isAdd) {
  36. if (!mapHeightTimes.containsKey(nodes[i].h)) {
  37. mapHeightTimes.put(nodes[i].h, 1);
  38. } else {
  39. mapHeightTimes.put(nodes[i].h, mapHeightTimes.get(nodes[i].h) + 1);
  40. }
  41. } else {
  42. if (mapHeightTimes.get(nodes[i].h) == 1) {
  43. mapHeightTimes.remove(nodes[i].h);
  44. } else {
  45. mapHeightTimes.put(nodes[i].h, mapHeightTimes.get(nodes[i].h) - 1);
  46. }
  47. }
  48. if (mapHeightTimes.isEmpty()) {
  49. xMaxHeight.put(nodes[i].x, 0);
  50. } else {
  51. xMaxHeight.put(nodes[i].x, mapHeightTimes.lastKey());
  52. }
  53. }
  54. List<List<Integer>> ans = new ArrayList<>();
  55. for (Map.Entry<Integer, Integer> entry : xMaxHeight.entrySet()) {
  56. int curx = entry.getKey();
  57. int curMaxHeight = entry.getValue();
  58. if (ans.isEmpty() || ans.get(ans.size() - 1).get(1) != curMaxHeight) {
  59. ans.add(new ArrayList<>(Arrays.asList(curx, curMaxHeight)));
  60. }
  61. }
  62. return ans;
  63. }