하늘에서 비행기의 수
목록 이착륙 항공기, 주어진 시간은 순서 interval
. 하늘을 계산하세요 나타냅니다 항공기의 최대 수를하는 동안?
예
예 1 :
输入: [(1, 10), (2, 3), (5, 8), (4, 7)]
输出: 3
解释:
第一架飞机在1时刻起飞, 10时刻降落.
第二架飞机在2时刻起飞, 3时刻降落.
第三架飞机在5时刻起飞, 8时刻降落.
第四架飞机在4时刻起飞, 7时刻降落.
在5时刻到6时刻之间, 天空中有三架飞机.
아이디어 : 클래식 주사선 알고리즘 : 이벤트, 모든 앞에 착륙에 따라 정렬 뒤에 벗고도 같을 시간이 지남에 따라 배열, 헤어 졌 같은 간격 이륙 및 착륙, 그리고 마지막으로 다시 청소는 시작, ++ 계산을 만났다 대회의 끝, count--, 최대 값과 다음 마지막으로 중간에 나타났다는 요청의 대상이다.
/**
* Definition of Interval:
* public classs Interval {
* int start, end;
* Interval(int start, int end) {
* this.start = start;
* this.end = end;
* }
* }
*/
public class Solution {
/**
* @param airplanes: An interval array
* @return: Count of airplanes are in the sky.
*/
private class Node {
int time;
int flag; // 1 take off, 0 is landing;
public Node(int time, int flag) {
this.time = time;
this.flag = flag;
}
}
private class NodeComparator implements Comparator<Node> {
@Override
public int compare(Node a, Node b) {
if(a.time != b.time) {
return a.time - b.time;
} else {
// 定义1是起飞,0是下降,这样如果按照大小排序,那么就是如果时间相等的情况下:下降的在前面,起飞的在后面。
return a.flag - b.flag;
}
}
}
public int countOfAirplanes(List<Interval> airplanes) {
if(airplanes == null || airplanes.size() == 0) {
return 0;
}
int n = airplanes.size();
Node[] nodes = new Node[n * 2];
int index = 0;
for(Interval interval : airplanes) {
nodes[index++] = new Node(interval.start, 1);
nodes[index++] = new Node(interval.end, 0);
}
Arrays.sort(nodes, new NodeComparator());
int count = 0;
int maxcount = 0;
for(int i = 0; i < nodes.length; i++) {
if(nodes[i].flag == 1) {
count++;
}
if(nodes[i].flag == 0) {
count--;
}
maxcount = Math.max(count, maxcount);
}
return maxcount;
}
}
회의실 II
회의 시작 시간과 종료 시간을 포함하여 구간 간격의 일련을 감안할 [[s1,e1],[s2,e2],...] (si < ei)
필요 회의실의 최소 번호를 찾기 위해.
예
샘플 1
输入: intervals = [(0,30),(5,10),(15,20)]
输出: 2
解释:
需要两个会议室
会议室1:(0,30)
会议室2:(5,10),(15,20)
아이디어 : 코드가 같은 위의 제목과 같은 항공기 정확하게.
/**
* Definition of Interval:
* public classs Interval {
* int start, end;
* Interval(int start, int end) {
* this.start = start;
* this.end = end;
* }
* }
*/
public class Solution {
/**
* @param intervals: an array of meeting time intervals
* @return: the minimum number of conference rooms required
*/
private class Meeting {
public int time;
public int flag;
public Meeting (int time, int flag) {
this.time = time;
this.flag = flag; // define 1 as start, 0 as end;
}
}
private class MeetingComparator implements Comparator<Meeting> {
@Override
public int compare(Meeting a, Meeting b) {
if(a.time != b.time) {
return a.time - b.time;
} else {
return a.flag - b.flag;
}
}
}
public int minMeetingRooms(List<Interval> intervals) {
if(intervals == null || intervals.size() == 0) {
return 0;
}
int n = intervals.size();
Meeting[] meetings = new Meeting[n * 2];
int index = 0;
for(Interval interval : intervals) {
meetings[index++] = new Meeting(interval.start, 1);
meetings[index++] = new Meeting(interval.end, 0);
}
Arrays.sort(meetings, new MeetingComparator());
int count = 0;
int maxcount = 0;
for(int i = 0; i < meetings.length; i++) {
if(meetings[i].flag == 1) {
count++;
}
if(meetings[i].flag == 0) {
count--;
}
maxcount = Math.max(maxcount, count);
}
return maxcount;
}
}
시간 교차로
두 시간이 시리즈는 온라인 사용자는 각각의 섹션은 사용자의 로그온 지점 시간 기록,이 정렬 x
시간과 오프라인 점을 y
큰 작은에서, 같은 기간에 온라인으로 두 명의 사용자를 찾아, 당신의 출력의 기간을 . 당신은 간격의 목록을 반환해야
예
예 1 :
输入:seqA = [(1,2),(5,100)], seqB = [(1,6)]
输出:[(1,2),(5,6)]
解释:在 (1,2), (5,6) 这两个时间段内,两个用户同时在线。
샘플 2 :
输入:seqA = [(1,2),(10,15)], seqB = [(3,5),(7,9)]
输出:[]
解释:不存在任何时间段,两个用户同时在线。
주의
- 우리는 온라인 시계열의 길이를 보장합니다
1 <= len <= 1e6
. - 우리는 온라인 시계열 법적 보장, 즉, 특정 사용자의 온라인 시계열을 위해, 어떤 두 개의 간격으로 교차하지 않습니다.
사고 : 주사선 알고리즘, 임계 값이 변경되면 수집 될 때, 데이터 수집 횟수 = 2이어야 주목된다.
/**
* Definition of Interval:
* public classs Interval {
* int start, end;
* Interval(int start, int end) {
* this.start = start;
* this.end = end;
* }
* }
*/
public class Solution {
/**
* @param seqA: the list of intervals
* @param seqB: the list of intervals
* @return: the time periods
*/
private class Node {
public int time;
public int flag;
public Node(int time, int flag) {
this.time = time;
this.flag = flag;
}
}
private class NodeComparator implements Comparator<Node> {
@Override
public int compare(Node a, Node b) {
if(a.time != b.time) {
return a.time - b.time;
} else {
return a.flag - b.flag; // define flag 1 is online, 0 is offline;
}
}
}
public List<Interval> timeIntersection(List<Interval> seqA, List<Interval> seqB) {
List<Interval> result = new ArrayList<Interval>();
if(seqA == null || seqA.size() == 0 || seqB == null || seqB.size() == 0) {
return result;
}
int n = seqA.size();
int m = seqB.size();
Node[] nodes = new Node[n * 2 + m * 2];
int index = 0;
for(int i = 0; i < n; i++) {
nodes[index++] = new Node(seqA.get(i).start, 1);
nodes[index++] = new Node(seqA.get(i).end, 0);
}
for(int i = 0; i < m; i++) {
nodes[index++] = new Node(seqB.get(i).start, 1);
nodes[index++] = new Node(seqB.get(i).end, 0);
}
Arrays.sort(nodes, new NodeComparator());
int count = 0;
int start = 0;
int end = 0;
for(int i = 0; i < nodes.length; i++) {
if(nodes[i].flag == 1) {
count++;
if(count == 2) {
start = nodes[i].time;
}
}
if(nodes[i].flag == 0) {
if(count == 2) { //每次都是阈值发生变化的时候,收集interval;
end = nodes[i].time;
result.add(new Interval(start, end));
start = 0;
end = 0;
}
count--;
}
}
return result;
}
}
아이디어 2 :이 문제는 데이터가 정렬되어 있기 때문에, A와 B는 분류되어 있기 때문에, 다음 건강 경고 방법, 때마다 킥을 사용할 수 병합 배열과 함께.
맥스 (startA, startB) <최소 경우 (ENDA, endB) 간격 첨가 교차가 크고, 또 프리킥을 떠난 A, B 단부를 참조] O (N + M)
데이터 정렬 // 때문에, 다음 스캔 한 데이터를 중첩에 따라서, 최대 값, 최소값 단부 복용 시작
// 개시 <단부 나타내면이 중복인지, 그렇지 않으면, 오버랩 없을 것이다 드로의 작은 단부 반면 이 이탈 인 이상;
/**
* Definition of Interval:
* public classs Interval {
* int start, end;
* Interval(int start, int end) {
* this.start = start;
* this.end = end;
* }
* }
*/
public class Solution {
/**
* @param seqA: the list of intervals
* @param seqB: the list of intervals
* @return: the time periods
*/
public List<Interval> timeIntersection(List<Interval> seqA, List<Interval> seqB) {
List<Interval> result = new ArrayList<Interval>();
if(seqA == null || seqA.size() == 0 || seqB == null || seqB.size() == 0) {
return result;
}
int aIndex = 0;
int bIndex = 0;
// 因为数据是sorted,那么就按照overlap来扫描,也就是start取最大值,end取最小值,
// 如果start< end,表明有overlap,否则不会有overlap,同时end较小的扔掉,较大的留下;
while(aIndex < seqA.size() && bIndex < seqB.size()) {
int start = Math.max(seqA.get(aIndex).start, seqB.get(bIndex).start);
int end = Math.min(seqA.get(aIndex).end, seqB.get(bIndex).end);
if(start < end) {
result.add(new Interval(start, end));
}
if(seqA.get(aIndex).end < seqB.get(bIndex).end) {
aIndex++;
} else {
bIndex++;
}
}
return result;
}
}
수평면 N 타워 각 건물 그것은 트리플로 표현 될 수 있고, 매트릭스 형상 인 (start, end, height)
시작 시점, 종점 및 X 축 높이를 표현한다. 건물 사이의 거리를 취득하고 중첩 월부터 N 건물 하우징의 외부 형상.
여러 트리플렛의 외형의 표현이 프로파일은 종단의 위치 및 높이의 개시 위치를 나타내는 세 개의 숫자 (시작, 끝, 높이)를 각각 포함하는 삼중.
예
샘플 1
输入:
[
[1, 3, 3],
[2, 4, 4],
[5, 6, 1]
]
输出:
[
[1, 2, 3],
[2, 4, 4],
[5, 6, 1]
]
아이디어 : 스캔 라인 알고리즘; 참고 : 정렬, 정렬에 시간은 다음 x는 계산을 사용하지 않는 경우에만 크고 작은 계산, 동일 백업하는 경우, 전면에 큰 만들기 위해, 앞서 착륙 역 행의 다음 높이를했다. 또한, PQ는 비어있을 수 있고, 계산에 따라 0을 비우고;
public class Solution {
/**
* @param buildings: A list of lists of integers
* @return: Find the outline of those buildings
*/
private class Node {
private int x;
private int height;
private int flag;
public Node (int x, int height, int flag) {
this.x = x;
this.height = height;
this.flag = flag; // define flag = 1, start, flag = 0, end;
}
}
private class NodeComparator implements Comparator<Node> {
@Override
public int compare(Node a, Node b) {
if(a.x != b.x) {
return a.x - b.x;
} else {
if(a.flag != b.flag) {
return b.flag - a.flag; // 让起飞在前面;
} else {
return b.height - a.height;
// 让高度最大的排前面;这样,同样x的,只考虑最高的;
}
}
}
}
public List<List<Integer>> buildingOutline(int[][] buildings) {
List<List<Integer>> lists = new ArrayList<List<Integer>>();
if(buildings == null || buildings.length == 0 || buildings[0].length == 0) {
return lists;
}
int n = buildings.length;
Node[] nodes = new Node[n * 2];
PriorityQueue<Integer> pq = new PriorityQueue<Integer>(n * 2, Collections.reverseOrder());
int index = 0;
for(int i = 0; i < n; i++) {
int start = buildings[i][0];
int end = buildings[i][1];
int height = buildings[i][2];
nodes[index++] = new Node(start, height, 1);
nodes[index++] = new Node(end, height, 0);
}
Arrays.sort(nodes, new NodeComparator());
int preheight = 0;
List<Node> candidates = new ArrayList<Node>();
for(int i = 0; i < nodes.length; i++) {
if(nodes[i].flag == 1) {
pq.add(nodes[i].height);
}
if(nodes[i].flag == 0) {
pq.remove(nodes[i].height);
}
int curheight = pq.isEmpty() ? 0 : pq.peek(); // 判断pq是否为空;
if(preheight != curheight) {
candidates.add(new Node(nodes[i].x, curheight, -1));
preheight = curheight;
}
}
convertCandiate(candidates, lists);
return lists;
}
private void convertCandiate(List<Node> candidates, List<List<Integer>> lists) {
List<Integer> list = new ArrayList<Integer>();
for(int i = 0; i < candidates.size() -1; i++) {
Node first = candidates.get(i);
Node second = candidates.get(i+1);
if(first.height == 0 || first.x == second.x) {
continue;
} else {
list.add(first.x);
list.add(second.x);
list.add(first.height);
lists.add(new ArrayList<Integer>(list));
list = new ArrayList<Integer>();
}
}
}
}