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

2023-11-06 12:44

本文主要是介绍力扣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;}
}

这篇关于力扣218.天际线问题 线段树解法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/356701

相关文章

关于@MapperScan和@ComponentScan的使用问题

《关于@MapperScan和@ComponentScan的使用问题》文章介绍了在使用`@MapperScan`和`@ComponentScan`时可能会遇到的包扫描冲突问题,并提供了解决方法,同时,... 目录@MapperScan和@ComponentScan的使用问题报错如下原因解决办法课外拓展总结@

MybatisGenerator文件生成不出对应文件的问题

《MybatisGenerator文件生成不出对应文件的问题》本文介绍了使用MybatisGenerator生成文件时遇到的问题及解决方法,主要步骤包括检查目标表是否存在、是否能连接到数据库、配置生成... 目录MyBATisGenerator 文件生成不出对应文件先在项目结构里引入“targetProje

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

numpy求解线性代数相关问题

《numpy求解线性代数相关问题》本文主要介绍了numpy求解线性代数相关问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 在numpy中有numpy.array类型和numpy.mat类型,前者是数组类型,后者是矩阵类型。数组

解决systemctl reload nginx重启Nginx服务报错:Job for nginx.service invalid问题

《解决systemctlreloadnginx重启Nginx服务报错:Jobfornginx.serviceinvalid问题》文章描述了通过`systemctlstatusnginx.se... 目录systemctl reload nginx重启Nginx服务报错:Job for nginx.javas

Redis缓存问题与缓存更新机制详解

《Redis缓存问题与缓存更新机制详解》本文主要介绍了缓存问题及其解决方案,包括缓存穿透、缓存击穿、缓存雪崩等问题的成因以及相应的预防和解决方法,同时,还详细探讨了缓存更新机制,包括不同情况下的缓存更... 目录一、缓存问题1.1 缓存穿透1.1.1 问题来源1.1.2 解决方案1.2 缓存击穿1.2.1

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言

解决Cron定时任务中Pytest脚本无法发送邮件的问题

《解决Cron定时任务中Pytest脚本无法发送邮件的问题》文章探讨解决在Cron定时任务中运行Pytest脚本时邮件发送失败的问题,先优化环境变量,再检查Pytest邮件配置,接着配置文件确保SMT... 目录引言1. 环境变量优化:确保Cron任务可以正确执行解决方案:1.1. 创建一个脚本1.2. 修

Python 标准库time时间的访问和转换问题小结

《Python标准库time时间的访问和转换问题小结》time模块为Python提供了处理时间和日期的多种功能,适用于多种与时间相关的场景,包括获取当前时间、格式化时间、暂停程序执行、计算程序运行时... 目录模块介绍使用场景主要类主要函数 - time()- sleep()- localtime()- g