掃描問題的特點
1 事件往往是以區間的形式存在
2 區間兩端代表事件的開始和結束
3 按照區間起點排序,起點相同的按照終點拍排序
掃描線要點
將起點和終點打散排序
[[1,3], [2,4]] => [[1,start],[2,start],[3,end],[4,end]]
391 Number of Airplanes in the Sky
- 降落-1 起飛+1
- 遇到一個-1總數-1 遇到一個+1總數+1
- 因為題目說同時有起飛降落時先考慮降落 所以排序時降落的在前
218 The Skyline Problem
- 花花醬 LeetCode 218. The Skyline Problem講解的非常好
todo
919 Meeting Rooms II
821 Time Intersection
lt391 Number of Airplanes in the Sky
class Pair{
int index;
int delta;
Pair(int index, int delta){
this.index = index;
this.delta = delta;
}
}
public class Solution {
/**
* @param airplanes: An interval array
* @return: Count of airplanes are in the sky.
*/
public int countOfAirplanes(List<Interval> airplanes) {
// write your code here
if(airplanes==null || airplanes.size()==0)
return 0;
List<Pair> list = new ArrayList<>();
for(Interval interval : airplanes){
list.add(new Pair(interval.start, 1));
list.add(new Pair(interval.end, -1));
}
Comparator<Pair> com = new Comparator<Pair>(){
public int compare(Pair a, Pair b){
if(a.index!=b.index){
return a.index-b.index;
}else{
return a.delta-b.delta;
}
}
};
Collections.sort(list, com);
int count = 0;
int max = Integer.MIN_VALUE;
for(Pair pair : list){
count = count + pair.delta;
max = Math.max(max, count);
}
return max;
}
}
218 The Skyline Problem
class Solution {
class Event{
int height;
int eventType;
int index;
Event(int height, int eventType, int index){
this.height = height;
//0 entering; 1 leaving
this.eventType = eventType;
this.index = index;
}
}
public List<int[]> getSkyline(int[][] buildings) {
List<int[]> results = new ArrayList<>();
if(buildings==null || buildings.length==0 || buildings[0]==null || buildings[0].length==0)
return results;
List<Event> list = new ArrayList<>();
for(int i=0; i<buildings.length; i++){
list.add(new Event(buildings[i][2], 0, buildings[i][0]));
list.add(new Event(buildings[i][2], 1, buildings[i][1]));
}
System.out.println(list.size());
Comparator<Event> com = new Comparator<Event>(){
public int compare(Event a, Event b){
if(a.index!=b.index)
//坐標不同先按處理坐標小的
return a.index-b.index;
if(a.eventType!=b.eventType){
//事件類型不同時 先考慮進入事件
return a.eventType-b.eventType;
}
if(a.eventType==0){
//都是進入事件時 先處理高的
return b.height-a.height;
}
//都是離開事件時 先處理高的
return a.height-b.height;
}
};
Collections.sort(list, com);
Queue<Integer> maxHeap = new PriorityQueue<Integer>(Collections.reverseOrder());
maxHeap.offer(0);
for(Event event : list){
//答案只會出現在有新的大樓進入 或者有大樓離開
if(event.eventType==0){
//是進入事件
if(maxHeap.peek()<event.height){
int[] result = {event.index, event.height};
results.add(result);
}
maxHeap.offer(event.height);
}else{
//是離開事件
maxHeap.remove(event.height);
if(maxHeap.peek()<event.height){
int[] result = {event.index, maxHeap.peek()};
results.add(result);
}
}
}
return results;
}
}