• 给定一个 N×3 的矩阵 matrix,对于每一个长度为 3 的小数组 arr,都表示一个大楼的三个数据,请返回整体的轮廓线数组。


    问题描述

            给定一个 N×3 的矩阵 matrix,对于每一个长度为 3 的小数组 arr,都表示一个大楼的三个数 据。arr[0]表示大楼的左边界,arr[1]表示大楼的右边界,arr[2]表示大楼的高度(一定大于 0)。 每座大楼的地基都在 X 轴上,大楼之间可能会有重叠,请返回整体的轮廓线数组。

    【举例】 matrix ={{2,5,6}, {1,7,4}, {4,6,7}, {3,6,5}, {10,13,2}, {9,11,3}, {12,14,4},{10,12,5} }

    返回: {{1,2,4},{2,4,6}, {4,6,7}, {6,7,4}, {9,10,3}, {10,12,5}, {12,14,4}}

    代码

    1. //描述高度变化的对象
    2. public static class Op {
    3. public int x;//x轴上的值
    4. public boolean isAdd;//true为加入,false为删除
    5. public int h;//高度
    6. public Op(int x, boolean isAdd, int h) {
    7. this.x = x;
    8. this.isAdd = isAdd;
    9. this.h = h;
    10. }
    11. }
    12. /**
    13. * 排序的比较策略
    14. * 1.第一个维度的X值从小到大。
    15. * 2.如果第一个维度的值相同,看第二个维度的值,“加入”排在前,“删除”排在后
    16. * 3.如果两个对象第一维度和第二个维度的值都相同,则认为两个对象相同,谁在前都行
    17. */
    18. public static class OpComparator implements Comparator {
    19. @Override
    20. public int compare(Op o1, Op o2) {
    21. if (o1.x != o2.x) {
    22. return o1.x - o2.x;
    23. }
    24. if (o1.isAdd != o2.isAdd) {
    25. return o1.isAdd ? -1 : 1;
    26. }
    27. return 0;
    28. }
    29. }
    30. public static List> buildingOutline(int[][] matrix) {
    31. int N = matrix.length;
    32. Op[] ops = new Op[N << 1];
    33. for (int i = 0; i < matrix.length; i++) {
    34. ops[i * 2] = new Op(matrix[i][0], true, matrix[i][2]);
    35. ops[i * 2 + 1] = new Op(matrix[i][1], false, matrix[i][2]);
    36. }
    37. //把描述高度变化的对象数组,按照规定的排序策略排序
    38. Arrays.sort(ops, new OpComparator());
    39. // key : 某个高度 value : 次数
    40. TreeMap mapHeightTimes = new TreeMap<>();
    41. // key : x点 value : 最大高度
    42. TreeMap mapXHeight = new TreeMap<>();
    43. for (int i = 0; i < ops.length; i++) {
    44. //如果当前是加入操作
    45. if (ops[i].isAdd) {
    46. //没有出现的高度
    47. if (!mapHeightTimes.containsKey(ops[i].h)) {
    48. mapHeightTimes.put(ops[i].h, 1);
    49. } else {//之前出现的高度,次数加一即可
    50. mapHeightTimes.put(ops[i].h, mapHeightTimes.get(ops[i].h) + 1);
    51. }
    52. } else {//如果当前是删除操作
    53. //如果当前的高度出现的次数为1,直接删除
    54. if (mapHeightTimes.get(ops[i].h) == 1) {
    55. mapHeightTimes.remove(ops[i].h);
    56. } else {//如果当前高度出现的次数大于1,次数减1即可
    57. mapHeightTimes.put(ops[i].h, mapHeightTimes.get(ops[i].h) - 1);
    58. }
    59. }
    60. //根据mapHeightTimes中的最大高度,设置mapXHeight
    61. //mapHeightTimes为空,说明最大高度为0
    62. if (mapHeightTimes.isEmpty()) {
    63. mapXHeight.put(ops[i].x, 0);
    64. } else {
    65. //mapHeightTimes不为空,获取最大高度
    66. mapXHeight.put(ops[i].x, mapHeightTimes.lastKey());
    67. }
    68. }
    69. //res为结果数组,每一个List代表一个轮廓线,有开始位置,结束位置,高度一共三个信息
    70. List> res = new ArrayList<>();
    71. //一个新轮廓线的开始位置
    72. int start = 0;
    73. //之前的最大高度
    74. int preHeight = 0;
    75. for (Map.Entry entry : mapXHeight.entrySet()) {
    76. //当前位置
    77. int curX = entry.getKey();
    78. //当前最大高度
    79. int curMaxHeight = entry.getValue();
    80. //之前最大高度和当前最大高度不一样时
    81. if (preHeight != curMaxHeight) {
    82. if (preHeight != 0) {
    83. res.add(new ArrayList<>(Arrays.asList(start, curX, preHeight)));
    84. }
    85. start = curX;
    86. preHeight = curMaxHeight;
    87. }
    88. }
    89. return res;
    90. }
    91. public static void main(String[] args) {
    92. int[][] matrix = {
    93. {2, 5, 6},
    94. {1, 7, 4},
    95. {4, 6, 7},
    96. {3, 6, 5},
    97. {10, 13, 2},
    98. {9, 11, 3},
    99. {12, 14, 4},
    100. {10, 12, 5}
    101. };
    102. List> res = buildingOutline(matrix);
    103. System.out.println(res);
    104. }

  • 相关阅读:
    客服岗位需要一个知识库吗?
    Maven的安装、配置以及在Eclipse中安装maven插件
    Spring JDBCTemplate简介
    操作系统文件共享方式
    软考高级系统架构设计师系列论文真题九:论软件多层架构的设计
    ubuntu源码安装aria2
    LLM文章阅读:Baichuan 2 干货
    Android并发编程与多线程
    WebRTC 日志
    VTK笔记——拾取器 Picker 汇总
  • 原文地址:https://blog.csdn.net/z1171127310/article/details/128170912