Skip to content

Commit 1dff672

Browse files
committed
Sweep line, deque
1 parent 22bb0b4 commit 1dff672

10 files changed

Lines changed: 1666 additions & 769 deletions

‎GenerateCodeTable.java‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public static void main(String[] args) {
9595
gct.printTable("ReviewPage.md", outputContent);
9696
} else if (args != null && args[0].contains("tags")) {//Wordpress
9797
outputContent = gct.generateTagREADME(listOfFiles);
98-
gct.printTable("TagsREADME.txt", outputContent);
98+
gct.printTable("TagREADME.md", outputContent);
9999
} else if (args != null && args[0].contains("all")) {
100100
outputContent = gct.generateREADME(listOfFiles);
101101
gct.printTable("README.md", outputContent);
@@ -104,7 +104,7 @@ public static void main(String[] args) {
104104
outputContent = gct.generateReviewPage(listOfFiles);
105105
gct.printTable("ReviewPage.md", outputContent);
106106
outputContent = gct.generateTagREADME(listOfFiles);
107-
gct.printTable("TagsREADME.md", outputContent);
107+
gct.printTable("TagREADME.md", outputContent);
108108
outputContent = gct.generateTagReviewPage(listOfFiles);
109109
gct.printTable("TagReviewPage.md", outputContent);
110110
}

‎Java/Building Outline.java‎

Lines changed: 117 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,126 @@
1-
H
1+
R
2+
1521176156
3+
tags: Divide and Conquer, Heap, Binary Indexed Tree, Segment Tree, Sweep Line
24

3-
又叫做skyline
5+
又叫做skyline. 用Sweep Line做的O(nLogN), 但是貌似还有很多做法: segement tree, hashheap, treeSet?
46

5-
看网上的解答做, 思路很漂亮。 (http://codechen.blogspot.com/2015/06/leetcode-skyline-problem.html?_sm_au_=isVmHvFmFs40TWRt)
7+
#### 方法1: Sweep Line, Time O(nLogN), Space O(n)
8+
original reference http://codechen.blogspot.com/2015/06/leetcode-skyline-problem.html?_sm_au_=isVmHvFmFs40TWRt
69

7-
跟scan line的approach类似:
8-
1. 把所有点分出来, 每个点有index x, 再加上一个height.
9-
2. 在这个list上排序,根据index和height(注意用负数标记building start point,这样保证start在end 之前。). 叫做 heightPoints
10-
3. 在processs时候用max-heap (reversed priorityqueue),在ieteraete heightPoints 来存最大的height . 遇到peek,就是一个合理的解
11-
处理1:因为start,end的height都存在了heightPoints里面,这里就是用来check end of bulding的,然后把height 从queue里面remove.
12-
处理2:重复x 上面的许多height? priorityqueue给了我们最高,这okay了;那么其他的重复点,用一个int prev来mark之前做过的,一旦重复,跳过。
10+
sweep line:
11+
- 把所有点分出来, 每个点有index x, 再加上一个height.
12+
- 在这个list上排序,根据index和height. 注意用负数标记building start point height, 这样保证start在end 之前
13+
- 用负数的height标记start: 在priority queue里面同一个x-pos比较 startPoint.height, endPoint.height 的时候, 因为end height是整数, 所以compare时会自动把start point放在end point前面
14+
- 当然了, 如果两个 start point比较, 第二个point的负数超大的话(也就是height很高), 就会顺理compare return正数, 成章形成倒位
15+
- 在processs时候用max-heap (reversed priorityqueue),再iterate heightPoints 来存最大的height . 遇到peek,就是一个合理的解
16+
- heightQueue里面加一个0, 用来在结尾的时候做closure
1317

14-
想法非常natural。 大题目,脑子乱。
15-
看了解答再去想,挺naturally doable的。
18+
#### 方法2: Segment Tree
19+
REVIEW
20+
21+
Binary Indexed Tree?
22+
23+
HashHeap?
1624

1725
```
26+
/*
27+
LeetCode:
28+
A city's skyline is the outer contour of the silhouette formed by all the buildings in that city
29+
when viewed from a distance. Now suppose you are given the locations and height of all the buildings
30+
as shown on a cityscape photo (Figure A), write a program to output the skyline formed by these buildings
31+
collectively (Figure B).
32+
33+
The geometric information of each building is represented by a triplet of integers [Li, Ri, Hi],
34+
where Li and Ri are the x coordinates of the left and right edge of the ith building, respectively,
35+
and Hi is its height. It is guaranteed that 0 ≤ Li, Ri ≤ INT_MAX, 0 < Hi ≤ INT_MAX, and Ri - Li > 0.
36+
You may assume all buildings are perfect rectangles grounded on an absolutely flat surface at height 0.
37+
38+
For instance, the dimensions of all buildings in Figure A are recorded as:
39+
[ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ] .
40+
41+
The output is a list of "key points" (red dots in Figure B) in the format of
42+
[ [x1,y1], [x2, y2], [x3, y3], ... ] that uniquely defines a skyline.
43+
A key point is the left endpoint of a horizontal line segment. Note that the last key point,
44+
where the rightmost building ends, is merely used to mark the termination of the skyline,
45+
and always has zero height. Also, the ground in between any two adjacent buildings
46+
should be considered part of the skyline contour.
47+
48+
For instance, the skyline in Figure B should be represented as:
49+
[ [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0] ].
50+
51+
Notes:
52+
53+
The number of buildings in any input list is guaranteed to be in the range [0, 10000].
54+
The input list is already sorted in ascending order by the left x position Li.
55+
The output list must be sorted by the x position.
56+
There must be no consecutive horizontal lines of equal height in the output skyline. For instance, [...[2 3], [4 5], [7 5], [11 5], [12 7]...] is not acceptable; the three lines of height 5 should be merged into one in the final output as such: [...[2 3], [4 5], [12 7], ...]
57+
58+
*/
59+
60+
/*
61+
Thoughts:
62+
Sweep Line.
63+
1. Store the building start/end points into a Point object.
64+
2. PriorityQueue on the Point: height low -> high && position lowX -> highX
65+
3. Loop over PointQueue, and store the heights in a separate maxQueue
66+
4. Based on the currPeak and prevPeak to detect diff: when there is a diff, there is a recording point.
67+
Keeping add start height into the maxHeap, and remove end points whenever facing one.
68+
69+
*/
70+
class Solution {
71+
class Point {
72+
int pos;
73+
int height;
74+
public Point(int pos, int height) {
75+
this.pos = pos;
76+
this.height = height;
77+
}
78+
}
79+
public List<int[]> getSkyline(int[][] buildings) {
80+
List<int[]> rst = new ArrayList<>();
81+
if (buildings == null || buildings.length == 0 || buildings[0] == null || buildings[0].length == 0) {
82+
return rst;
83+
}
84+
int m = buildings.length;
85+
// Sort points(xPos, height, isStart:boolean) by height && xPos with queue
86+
PriorityQueue<Point> queue = new PriorityQueue<Point>(new Comparator<Point>() {
87+
public int compare(Point a, Point b) {
88+
if (a.pos == b.pos) {
89+
return a.height - b.height;
90+
} else {
91+
return a.pos - b.pos;
92+
}
93+
}
94+
});
95+
for (int i = 0; i < m; i++) {
96+
queue.offer(new Point(buildings[i][0], -buildings[i][2]));
97+
queue.offer(new Point(buildings[i][1], buildings[i][2]));
98+
}
99+
100+
// Mark height and calcualte the outline point.
101+
PriorityQueue<Integer> maxHeightQueue = new PriorityQueue<>(Collections.reverseOrder());
102+
maxHeightQueue.offer(0);
103+
int prevPeak = maxHeightQueue.peek();
104+
105+
while (!queue.isEmpty()) {
106+
Point point = queue.poll();
107+
if (point.height < 0) {
108+
maxHeightQueue.offer(-point.height);
109+
} else { // is end point of a building
110+
maxHeightQueue.remove(point.height);
111+
}
112+
113+
int currPeak = maxHeightQueue.peek();
114+
if (currPeak != prevPeak) {
115+
rst.add(new int[]{point.pos, currPeak});
116+
prevPeak = currPeak;
117+
}
118+
}
119+
return rst;
120+
}
121+
}
122+
123+
18124
/*
19125
LintCode description:
20126
Given N buildings in a x-axis,each building is a rectangle and can be represented by a triple (start, end, height),

‎Java/Meeting Rooms II.java‎

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
M
2+
1521167295
3+
tags: Heap, Greedy, Sort, Sweep Line
24

5+
给一串数字pair, 代表会议的开始/结束时间. 找同时又多少个会议发生(需要多少件房间)
36

4-
方法1:PriorityQueue + 一个Class来解决。O(nlogn)
7+
#### 方法1
8+
- PriorityQueue + 一个Class来解决.O(nlogn)
9+
- 跟 Number of Airpline in the sky是同一道题
510

6-
方法2:这里有尝试了一下用一个sorted Array + HashMap: 也还行,但是handle edge的时候,HashMap 要小心,因为相同时间start和end的map key 就会重复了。
11+
#### 方法2: 尝试了一下用一个sorted Array + HashMap
12+
也还行,但是handle edge的时候,HashMap 要小心,因为相同时间start和end的map key 就会重复了。
713

814
```
915
/*
@@ -19,13 +25,26 @@
1925
*/
2026

2127

22-
23-
24-
// Similar to Meeting Room I, using Point class and Priorityqueue
25-
// Creating a customized class, but makes the problem a bit easier to think.
26-
public class Solution {
28+
/**
29+
* Definition for an interval.
30+
* public class Interval {
31+
* int start;
32+
* int end;
33+
* Interval() { start = 0; end = 0; }
34+
* Interval(int s, int e) { start = s; end = e; }
35+
* }
36+
*/
37+
/*
38+
Thoughts:
39+
Counts the num of concurrent meetings.
40+
Use sweep line to modle the inverval into time Points, where 1 means start of meeting and -1 means end of meeting.
41+
Sort all points by time stamp, and accumulate +1, -1
42+
Mark the max of count
43+
*/
44+
class Solution {
2745
class Point {
28-
int pos, flag;
46+
int pos;
47+
int flag;
2948
public Point(int pos, int flag) {
3049
this.pos = pos;
3150
this.flag = flag;
@@ -35,30 +54,31 @@ public int minMeetingRooms(Interval[] intervals) {
3554
if (intervals == null || intervals.length == 0) {
3655
return 0;
3756
}
38-
39-
PriorityQueue<Point> queue = new PriorityQueue<Point>(2, new Comparator<Point>() {
40-
public int compare(Point p1, Point p2) {
41-
return p1.pos - p2.pos;
57+
int count = 0;
58+
int max = 0;
59+
PriorityQueue<Point> queue = new PriorityQueue<Point>(new Comparator<Point>() {
60+
public int compare(Point a, Point b) {
61+
return a.pos - b.pos;
4262
}
4363
});
4464

45-
for (int i = 0; i < intervals.length; i++) {
46-
queue.offer(new Point(intervals[i].start, 1));
47-
queue.offer(new Point(intervals[i].end, -1));
65+
for (Interval interval: intervals) {
66+
queue.offer(new Point(interval.start, 1));
67+
queue.offer(new Point(interval.end, -1));
4868
}
49-
int count = 0;
50-
int rst = 0;
69+
5170
while (!queue.isEmpty()) {
52-
Point p = queue.poll();
53-
count += p.flag;
54-
while (!queue.isEmpty() && p.pos == queue.peek().pos) {
55-
p = queue.poll();
56-
count += p.flag;
71+
Point curr = queue.poll();
72+
count += curr.flag;
73+
while (!queue.isEmpty() && curr.pos == queue.peek().pos) {
74+
curr = queue.poll();
75+
count += curr.flag;
5776
}
58-
rst = Math.max(count, rst);
77+
78+
max = Math.max(count, max);
5979
}
6080

61-
return rst;
81+
return max;
6282
}
6383
}
6484

‎Java/Sliding Window Maximum.java‎

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,81 @@
33
为啥可以不管不无地剔除?
44
因为我们只在乎最大值的存在;而任何小于当前(正要新就加进去的)值的,反正以后也成不了最大值,于是扔掉!
55
```
6+
/*
7+
LeetCode:
8+
Given an array nums, there is a sliding window of size k which is moving
9+
from the very left of the array to the very right.
10+
You can only see the k numbers in the window.
11+
Each time the sliding window moves right by one position.
12+
13+
For example,
14+
Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.
15+
16+
Window position Max
17+
--------------- -----
18+
[1 3 -1] -3 5 3 6 7 3
19+
1 [3 -1 -3] 5 3 6 7 3
20+
1 3 [-1 -3 5] 3 6 7 5
21+
1 3 -1 [-3 5 3] 6 7 5
22+
1 3 -1 -3 [5 3 6] 7 6
23+
1 3 -1 -3 5 [3 6 7] 7
24+
Therefore, return the max sliding window as [3,3,5,5,6,7].
25+
26+
Note:
27+
You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array.
28+
29+
Follow up:
30+
Could you solve it in linear time?
31+
32+
*/
33+
34+
/*
35+
Thoughts:
36+
Brutle way: for every k window, calculate the max O(nk)
37+
Can use priority queue to track max => O(nLogK) => O(nLogN)
38+
Linear time: O(n)?
39+
40+
Want to maintain the window, a deque, where right-most element in the window is the lowest value in the deque.
41+
1. when adding new element, we need to clean up the deque bottom
42+
2. when removing item, simply just match see if any top max is match; if match, remove it.
43+
44+
Deque always have all unique max values, with right-most window element as smallest max in the deque.
45+
46+
*/
47+
class Solution {
48+
public int[] maxSlidingWindow(int[] nums, int k) {
49+
if (nums == null || nums.length < k || k <= 0) {
50+
return new int[0];
51+
}
52+
int[] rst = new int[nums.length - k + 1];
53+
Deque<Integer> deque = new ArrayDeque<Integer>();
54+
for (int i = 0; i < k - 1; i++) {
55+
inQueue(deque, nums[i]);
56+
}
57+
58+
for (int i = k - 1; i < nums.length; i++) {
59+
inQueue(deque, nums[i]); // clean up and add new smallest maximum, if applicable
60+
rst[i - k + 1] = deque.peekFirst();
61+
outQueue(deque, nums[i - k + 1]); // remove top max if the num === max
62+
}
63+
return rst;
64+
}
65+
66+
private void inQueue(Deque<Integer> deque, int num) {
67+
while (!deque.isEmpty() && deque.peekLast() < num) { // top
68+
deque.pollLast();
69+
}
70+
deque.offerLast(num);
71+
}
72+
73+
private void outQueue(Deque<Integer> deque, int num) {
74+
if (deque.peekFirst() == num) {
75+
deque.pollFirst();
76+
}
77+
}
78+
}
79+
80+
681
/*
782
Given an array of n integer with duplicate number, and a moving window(size k), move the window at each iteration from the start of the array, find the maximum number inside the window at each moving.
883

‎KnowledgeHash2.md‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,15 @@ Segment Tree
139139
- 查找前缀
140140

141141

142+
### Deque
143+
- linear collection that supports insertion and removal at both ends. Pronounced 'deck'
144+
- It's a queue && stack
145+
- new ArrayDeque<Integer>()
146+
- head/top: offerFirst(), pollFirst(), peekFirst()
147+
- tail/bottom: offerLast(), pollLast(), peekLast()
148+
- 双端queue: 维护一个候选可能的最大值集合
149+
- ex: Sliding WIndow Maximum
150+
142151
### Graph
143152

144153
Graph
@@ -163,10 +172,12 @@ Two Pointers
163172
- 有时候在index上二分, mid是index; 但是有时候, 会在数值上二分, 那么mid就是value, 忌讳不要死板地套用nums[mid]
164173

165174
#### 二分思想
175+
- 按值二分,需要怎么二分性
166176
- 找到可能的解的范围
167177
- 猜答案
168178
- 检验答案 (match/if/else ...)
169179
- 调整搜索范围
180+
- Find Peak Element II
170181

171182
### Sort
172183

@@ -308,6 +319,13 @@ Design
308319
- 加一个数
309320
- 删一个数
310321

322+
##### Sweep Line
323+
- 见到区间需要排序就可以考虑扫描线
324+
- 事件往往是以区间的形式存在
325+
- 区间两端代表事件的开始和结束
326+
- 需要排序
327+
- Meeting Room I, II
328+
311329

312330

313331

0 commit comments

Comments
 (0)