@@ -95,4 +95,100 @@ public int compare(int[] v1, int[] v2) {
9595 return res ;
9696 }
9797
98+
99+ /**
100+ * https://leetcode.com/problems/the-skyline-problem/discuss/61192/Once-for-all-explanation-with-clean-Java-code(O(n2)time-O(n)-space)
101+ */
102+ public List <int []> getSkyline2 (int [][] buildings ) {
103+ List <int []> result = new ArrayList <>();
104+ List <int []> height = new ArrayList <>();
105+ for (int [] b :buildings ) {
106+ // start point has negative height value
107+ height .add (new int []{b [0 ], -b [2 ]});
108+ // end point has normal height value
109+ height .add (new int []{b [1 ], b [2 ]});
110+ }
111+
112+ // sort $height, based on the first value, if necessary, use the second to
113+ // break ties
114+ Collections .sort (height , (a , b ) -> {
115+ if (a [0 ] != b [0 ])
116+ return a [0 ] - b [0 ];
117+ return a [1 ] - b [1 ];
118+ });
119+
120+ // Use a maxHeap to store possible heights
121+ Queue <Integer > pq = new PriorityQueue <>((a , b ) -> (b - a ));
122+
123+ // Provide a initial value to make it more consistent
124+ pq .offer (0 );
125+
126+ // Before starting, the previous max height is 0;
127+ int prev = 0 ;
128+
129+ // visit all points in order
130+ for (int [] h :height ) {
131+ if (h [1 ] < 0 ) { // a start point, add height
132+ pq .offer (-h [1 ]);
133+ } else { // a end point, remove height
134+ pq .remove (h [1 ]);
135+ }
136+ int cur = pq .peek (); // current max height;
137+
138+ // compare current max height with previous max height, update result and
139+ // previous max height if necessary
140+ if (prev != cur ) {
141+ result .add (new int []{h [0 ], cur });
142+ prev = cur ;
143+ }
144+ }
145+ return result ;
146+ }
147+
148+
149+ /**
150+ * https://leetcode.com/problems/the-skyline-problem/discuss/61281/Java-divide-and-conquer-solution-beats-96
151+ */
152+ public List <int []> getSkyline3 (int [][] buildings ) {
153+ return merge (buildings , 0 , buildings .length -1 );
154+ }
155+
156+ private LinkedList <int []> merge (int [][] buildings , int lo , int hi ) {
157+ LinkedList <int []> res = new LinkedList <>();
158+ if (lo > hi ) {
159+ return res ;
160+ } else if (lo == hi ) {
161+ res .add (new int []{buildings [lo ][0 ], buildings [lo ][2 ]});
162+ res .add (new int []{buildings [lo ][1 ], 0 });
163+ return res ;
164+ }
165+ int mid = lo +(hi -lo )/2 ;
166+ LinkedList <int []> left = merge (buildings , lo , mid );
167+ LinkedList <int []> right = merge (buildings , mid +1 , hi );
168+ int leftH = 0 , rightH = 0 ;
169+ while (!left .isEmpty () || !right .isEmpty ()) {
170+ long x1 = left .isEmpty ()? Long .MAX_VALUE : left .peekFirst ()[0 ];
171+ long x2 = right .isEmpty ()? Long .MAX_VALUE : right .peekFirst ()[0 ];
172+ int x = 0 ;
173+ if (x1 < x2 ) {
174+ int [] temp = left .pollFirst ();
175+ x = temp [0 ];
176+ leftH = temp [1 ];
177+ } else if (x1 > x2 ) {
178+ int [] temp = right .pollFirst ();
179+ x = temp [0 ];
180+ rightH = temp [1 ];
181+ } else {
182+ x = left .peekFirst ()[0 ];
183+ leftH = left .pollFirst ()[1 ];
184+ rightH = right .pollFirst ()[1 ];
185+ }
186+ int h = Math .max (leftH , rightH );
187+ if (res .isEmpty () || h != res .peekLast ()[1 ]) {
188+ res .add (new int []{x , h });
189+ }
190+ }
191+ return res ;
192+ }
193+
98194}
0 commit comments