Title Source: https://leetcode.com/submissions/detail/47013144/
Test Instructions Description:
The left coordinate of the given series of rectangles is Li, the right coordinate ri, and the height hi (where Li is arranged in order from small to large). Represents a tall building in a city. These rectangles represent the skyline in which the tall buildings line up. The skyline is defined as the silhouette seen in the distance of all these tall buildings.
Data input:
[[L1, R1, H1], [Li, Ri, Hi] ...] A vector of three-dimensional vectors of element type, where the meaning of Li,ri,hi is described in test instructions. And the input data is guaranteed: 0 ≤ Li, Ri ≤ INT_MAX
, and 0 < Hi ≤ INT_MAX
Ri - Li > 0
Result output:
[[X1, Y1], [x2, y2] ...] A vector with the element type pair, where Xi represents the endpoint x-coordinate value of the I-level segment in the Skyline, and Yi represents the height of the horizontal line segment. It is important to note that because the skyline of the city is also part of the city's skyline, the last pair of the output must have a Y value of 0, representing the skyline from which the Y value will be 0.
Solution Ideas:
Idea One:
First of all, to see this problem, the first and simplest idea is to go straight through each X-value and look for each interval to cover the X-value and find the maximum, but, obviously, up to O (m) space complexity and O (nm) time complexity (M is the maximum x value, n is the number of intervals) will definitely kneel, so we need to change the idea.
Idea two:
Since we only care about a segment of the line, so Lenovo can be achieved through the line segment tree to achieve this problem, the input line to traverse the process can be. However, the tedious process of achievement for all of us and countless large operations of the yards of the farm simply can not endure (in fact, the real reason is only know the name of the line tree, never personally realized, dare not rushed into the pit), interested students can see the code implementation of 1. Of course, the segment tree is also a relatively important data structure, algorithm competition will occasionally involve, the line tree is interested in the students can own Baidu or Google related information. Here is only attached to a contest question "borrowing the classroom" Report of the noip2012 year (don't ask me why I remember so clearly, because I used to think of a simple rough method of thinking that the results only 30 points).
Three ideas:
Since both of these methods are kneeling, what better way to do that? Thought two in the line to see as a whole idea worthy of reference, although do not want to make their own achievements, but can directly use the existing tree in C + +. After all, the Map,multimap,set,muiltset in the STL is a ready-made red-and-black tree.
So we started a long road to document search, and we wanted to find something that could be used in these template data structures. First, since Li,ri are likely to reach Int_max scale, we need to map a series of coordinates of data size 0~int_max to a suitable table, that is, to create a hash list. The Multimap can be implemented to map the X-values of the endpoints in the segment, and the Y-values to the internal key values. So we just have to throw the Li,ri into the muitimap. But then the problem arose, and after throwing the Li,ri all over the multimap, we couldn't distinguish between the value of the X-value that belongs to the left of a rectangle, the value to the right. A relatively simple idea is to throw Li,ri into the muitimap, while binding its height information, if it is Li, bind Hi, if ri, then bind-hi (thank the Friends of God to provide this perfect idea to me, manual @gdp). As a result, the mapping problem is solved, and the scale of the data becomes 20000 acceptable to us.
Next we need to solve the problem of solving the height of each segment, one way is to use a priority queue to store the height of all segments that can be overwritten to that point under the current X value. As follows, the first initialization in the priority queue to insert element 0, and then traverse each endpoint (including the left and right endpoints), if the left end point, then the current corresponding height hi into the queue, if it is the right endpoint, the corresponding height-hi of the absolute value of the corresponding element is deleted from the queue, added or deleted , the maximum height in the priority queue can be obtained in O (1) for the maximum value of the current point. However, it is disappointing that the priority queue supports the insert operation and does not support any deletion, so we need to look for a template class that can be automatically sorted and quickly deleted in place of the priority queue. Obviously Multiset is a very good choice, so we have the following code (is not know what Multimap should take what name, so feel free to take a, embarrassed ~):
1 classSolution {2 Public:3vector<pair<int,int>> Getskyline (vector<vector<int>>&buildings) {4multimap<int,int>A;5vector<pair<int,int>>ans;6 for(inti =0; I < buildings.size (); i + +)7 {8A.emplace (buildings[i][0], buildings[i][2]);9A.emplace (buildings[i][1],-buildings[i][2]);Ten }; One Amultiset<int>h; -H.insert (0); - for(std::multimap<int,int>::iterator it = A.begin (); It!=a.end (); ++it) the { - if(It->second >0) - { -H.insert (it->second); + } - Else + { Astd::multiset<int>::iterator it_tmp = H.find (-it->second); at h.erase (it_tmp); - } - intHeight = *H.rbegin (); -Ans.push_back (pair<int,int> (it->First , height)); - } - returnans; in }; -};
Pleased to submit the code on the OJ found that, although the height is true, but did not do any exception processing, such as input [[2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8]], this code will give [[2 10],[3 15],[5 15],[7 12],[9 12],[12 0],[15 10],[19 10],[20 8],[24 0]] output, obviously many of the same height in the same place without processing directly output.
So we need to decide that if the height of the current position is consistent with the previous height, then we do not need to press into ans, so we can change the 26th line of code as follows:
if (ans.size () = = 0 | | Height! = ans.back (). Second) Ans.push_back (Pair<int, int> (it->first, height));
After making this change, the previous input was correct, but when the input changed to [[1 3 2],[3, 4, 4]], the output was [[1 2],[3 0],[3 3],[3 0]], which was obviously wrong, so I started some columns of the special sentence, some of the columns of the attempt, such as the 26th line made the following changes ( The code is really ugly can't read it):
1 if(ans.size () = =0|| Height! =Ans.back (). Second)2 {3 if(Ans.size ()! =0&& Ans.back (). First = = It->first && ans.back (). Second <height)4 Ans.pop_back ();5 if(ans.size () = =0|| ((Ans.back (). First! = It->first | | ans.back (). Second <height)6&& (Height! =Ans.back (). Second )))7Ans.push_back (pair<int,int> (it->First , height));8}
Finally, no matter how the adjustment, there is always a bunch of strange bugs, and my code is getting ugly, so I decided to give up, re-start looking at my bug, I found that as long as I each time the same x corresponding to all the hi has been processed and then the current height can be perfect to solve a series of bugs, So we have the following final version of the code:
1 classSolution {2 Public:3vector<pair<int,int>> Getskyline (vector<vector<int>>&buildings)4 {5multimap<int,int>A;6vector<pair<int,int>>ans;7 for(inti =0; I < buildings.size (); i + +)8 {9A.emplace (buildings[i][0], buildings[i][2]);TenA.emplace (buildings[i][1],-buildings[i][2]); One }; Amultiset<int>h; -H.insert (0); - for(std::multimap<int,int>::iterator it = A.begin (); It!=a.end (); ++it) the { - intKey = It->First ; - while(It! = A.end () && It->first = =key) - { + if(It->second >0) -H.insert (it->second); + Else AH.erase (H.find (-it->second)); atIt + +; - } -It--; - intHeight = *H.rbegin (); - if(ans.size () = =0|| Height! =Ans.back (). Second) -Ans.push_back (pair<int,int> (it->First , height)); in } - returnans; to }; +};
The whistling, finally ended, today (oh, yesterday seems to have gone!) is also low enough to write data structures efficiently. But through this experiment, in order to write a concise and efficient code, I really looked at a lot of documents AH, patience and English proficiency has been a great test.
Finally, I have a question that has not been wanted to understand, why this problem, from OJ on the submission of data, with Python,java and so write out of the speed than with c,c++ written out much faster? Is the reason why STL is not well written? Isn't c,c++ always known for its speed?
Attachment 1: Use segment tree to implement this problem https://leetcode.com/discuss/65620/share-my-solution-segment-tree-c-888ms
Attached 2:noip2012 to borrow classroom problem-solving report http://hzwer.com/2959.html
Problem Solving report: Leetcode the Skyline problem (painting the sky