当前位置: 首页 > news >正文

力扣218.天际线问题 线段树解法

原题

官解用的扫描线 + 优先队列方法,但是一开始没想的那么麻烦,只觉得这么有多区间,直觉暴力线段树,也提供一种思路

class Solution {//用线段树的结点范围代表x轴 结点值代表这段x轴内的最高高度//建完树之后如何获得答案呢? 再次遍历buildings数组//遍历每个建筑的左上点和右下点 如果其是这个区间最高点 就加入答案public List<List<Integer>> getSkyline(int[][] buildings) { //buildings[i] = [lefti, righti, heighti]int n = buildings.length;N = 1;for (int i = 0; i < n; i++) {N = Math.max(N, buildings[i][1]);// 找出线段树的范围 可以省一点时间}// 注意!区间最值的更新,为了避免覆盖情况,比如[15,20,10]和[19,24,8],需要按区间高度先排序Arrays.sort(buildings, (o1,o2) -> o1[2]-o2[2]);//按高度从小到大排序 这样就不会产生错误覆盖List<Integer> points = new ArrayList<>(); //存储边界坐标点for (int[] building : buildings) {int l = building[0],r=building[1],h=building[2];points.add(l);points.add(r);update(root,0,N,l,r-1,h);//建树 注意! 右边界的高度不算 防止端点覆盖}Collections.sort(points);//对坐标点排序points = points.stream().distinct().collect(Collectors.toList());//去除重复坐标点List<List<Integer>> ans = new ArrayList<>();//答案数组for (int i = 1; i < points.size(); i++) {int heigh=(int)query(root,0,N,points.get(i-1),points.get(i)-1);int j=i+1;while (j<points.size() && query(root,0,N,points.get(j-1),points.get(j)-1)==heigh) j++;//相同高度不算在天际线里ans.add(Arrays.asList(points.get(i-1),heigh));i = j-1;}ans.add(Arrays.asList(points.get(points.size()-1),0));//最后一个点坐标单独判断return ans;}//下面为线段树模版class Node {Node left, right;long val, add;}private int N;//线段树范围大小private Node root = new Node();public void update(Node node, long start, long end, long l, long r, long val) {if (l <= start && end <= r) {node.val = val;node.add = val;return;}long mid = (start + end) >> 1;pushDown(node, mid - start + 1, end - mid);if (l <= mid) update(node.left, start, mid, l, r, val);if (r > mid) update(node.right, mid + 1, end, l, r, val);pushUp(node);}// 在区间 [start, end] 中查询区间 [l, r] 的结果public long query(Node node, long start, long end, long l, long r) {if (l <= start && end <= r) return node.val;long mid = (start + end) >> 1, ans = 0;pushDown(node, mid - start + 1, end - mid);if (l <= mid) ans = query(node.left, start, mid, l, r);if (r > mid) ans = Math.max(ans, query(node.right, mid + 1, end, l, r));return ans;}// 向上更新private void pushUp(Node node) {node.val = Math.max(node.left.val, node.right.val);}// 推懒惰标记的函数private void pushDown(Node node, long leftNum, long rightNum) {if (node.left == null) node.left = new Node();if (node.right == null) node.right = new Node();if (node.add == 0) return;node.left.val = node.add;node.right.val = node.add;node.left.add = node.add;node.right.add = node.add;node.add = 0;}
}

相关文章:

  • Java零基础手把手保姆级教程_类和对象(超详细)
  • Leetcode48旋转图像
  • R语言环境下使用curl库做的爬虫代码示例
  • Android 图片翻面动画
  • 零日漏洞预防
  • IO学习系列之阻塞IO
  • Linux安装配置awscli命令行接口工具及其从aws上传下载数据
  • GPT技术的崛起:改变生活与挑战未来
  • ch0_OSI 七层网络协议介绍
  • 亚马逊云科技大语言模型下的六大创新应用功能
  • acwing算法基础之数据结构--堆算法
  • GPT与人类共生:解析AI助手的兴起
  • 乌干达市场开发攻略,收藏一篇就够了
  • Win11安装网络打印机
  • 2023-11-05 LeetCode每日一题(重复的DNA序列)
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • Apache Zeppelin在Apache Trafodion上的可视化
  • Docker: 容器互访的三种方式
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • React Transition Group -- Transition 组件
  • SQLServer之创建数据库快照
  • vue学习系列(二)vue-cli
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 对象管理器(defineProperty)学习笔记
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 面试遇到的一些题
  • 嵌入式文件系统
  • 使用common-codec进行md5加密
  • 微信小程序开发问题汇总
  • 一起来学SpringBoot | 第三篇:SpringBoot日志配置
  • ​ssh免密码登录设置及问题总结
  • ​VRRP 虚拟路由冗余协议(华为)
  • #pragma once
  • #考研#计算机文化知识1(局域网及网络互联)
  • ${factoryList }后面有空格不影响
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (09)Hive——CTE 公共表达式
  • (1)常见O(n^2)排序算法解析
  • (16)Reactor的测试——响应式Spring的道法术器
  • (C#)if (this == null)?你在逗我,this 怎么可能为 null!用 IL 编译和反编译看穿一切
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (附源码)ssm码农论坛 毕业设计 231126
  • (接口自动化)Python3操作MySQL数据库
  • (顺序)容器的好伴侣 --- 容器适配器
  • (太强大了) - Linux 性能监控、测试、优化工具
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • .axf 转化 .bin文件 的方法
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .form文件_一篇文章学会文件上传
  • .gitignore
  • .net 7 上传文件踩坑
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .NET gRPC 和RESTful简单对比
  • .NET MVC第五章、模型绑定获取表单数据