LeetCode 57. Insert Interval和 218. The Skyline Problem

这篇博客介绍了如何解决LeetCode上的两道难题:57.插入区间和218.天际线问题。解题策略涉及线段的并集计算,以及如何处理线段相交。对于57题,通过指针扫描和更新最大最小值实现区间合并;对于218题,利用线段相交的概念更新线段集合,同时注意线段的左闭右开特性。这两题都涉及到高效的区间操作和状态更新技巧。
摘要由CSDN通过智能技术生成

LeetCode 57. Insert Interval

  1. 学习了力扣中国官方给出的思路。有:如果两个线段之间没有交集,其充要条件为r1<l2。
    在这里插入图片描述
    本题可转化为求线段之间的并集。

  2. 另外,有一人提出了分成 3 个阶段考察的思路:用指针去扫 intervals,最多可能有三个阶段:
    在这里插入图片描述不重叠的绿区间,在蓝区间的左边
    有重叠的绿区间
    不重叠的绿区间,在蓝区间的右边

ac代码

class Solution {
    public int[][] insert(int[][] intervals, int[] newInterval) {
    	List<int[]> ans = new ArrayList<>();
    	int i=0;
    	for(;i<intervals.length && intervals[i][1]<newInterval[0];++i) {
    		ans.add(intervals[i]);
    	}
    	int midLeft=newInterval[0],midR=newInterval[1];
    	for(;i<intervals.length && intervals[i][0]<=newInterval[1];++i) {
    		midLeft = Math.min(midLeft, intervals[i][0]);
    		midR =  Math.max(midR, intervals[i][1]);
    	}
    	ans.add(new int[] {midLeft,midR});
    	for(;i<intervals.length;++i) {
    		ans.add(intervals[i]);
    	}
    	return ans.toArray(new int[0][]);
    }
}

218. The Skyline Problem

我的思路:可以把地面也看成高度为0的线段,题目转化为求线段相交。而且用新的线段newb遍历已生成的所有线段时,newb的任何部分都会与原有的某线段相交。另外有一点值得注意,因为题目要求是输出左边端点,所以我们定义本题的线段与上题不同,是左闭右开的,所以判断是否相交的标准也与上面略有区别。ac代码如下:

class Solution {
	public List<List<Integer>> getSkyline(int[][] buildings) {
		List<int[]> intervals = new ArrayList<>();
		intervals.add(new int[] { 0, Integer.MAX_VALUE, 0 });
		for (int i = 0; i < buildings.length; i++) {
			int[] newb = buildings[i];
			int j = 0;
			for (; j < intervals.size() && intervals.get(j)[1] <= newb[0]; ++j) {//左闭右开
			}
			for (; j < intervals.size() && intervals.get(j)[0] < newb[1]; ++j) {//左闭右开
				int[] inter = intervals.get(j);
				if (newb[2] > inter[2]) {
					int newL = Math.max(newb[0], inter[0]);
					int newR = Math.min(newb[1], inter[1]);
					int oldj = j;
					if(inter[0]<newL) {
						intervals.add(++j,new int[] { inter[0],newL,inter[2] }); 
					}
					intervals.add(++j,new int[] { newL,newR,newb[2] });  //
					if(inter[1]>newR) {
						intervals.add(++j,new int[] { newR,inter[1],inter[2] }); 
					}
					intervals.remove(oldj);
					--j;
				}
			}
		}
		
		List<List<Integer>> ans = new ArrayList<>();
		for (int i = 0; i < intervals.size(); i++) {
			if(i==0 && intervals.get(i)[2]==0)
				continue;
			if(i>0 && intervals.get(i)[2]==intervals.get(i-1)[2])
				continue;
			ans.add(Arrays.asList(intervals.get(i)[0],intervals.get(i)[2]));
			if(i==intervals.size()-1 && intervals.get(i)[2]>0)
				ans.add(Arrays.asList(intervals.get(i)[1],0));
		}
		return ans;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_23204557

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值