Leetcode: Trapping Rain water

Source: Internet
Author: User

Description

Given n non-negative integers representing an elevation map where the width of each bar are 1, compute how much WA ter It is the able to trap after raining.

For example,
Given [0,1,0,2,1,0,1,3,2,1,2,1] , return 6 .

"Chinese description"

Given n non-negative numbers, imagine that they represent the n wall, the height of the wall is NI, now imagine a rain, so that the wall can be saved how much water?

————————————————————————————————————————————————————————————

"Initial thinking"

This question is very interesting, so also did not see discuss, completely oneself hard just out of. In fact, this problem is not difficult, mainly test the degree of thought, and then step by step analysis can be.

I first thought is (Brutle not discuss it), with I traversal array, encounter than I high, stop, then calculate the amount of water inside, then update i.

This is the most basic idea, but there are a huge amount of detail to consider:

Detail 1: If I next one is taller than I or as high as I, obviously I this wall is useless, continue;

OK, I the next wall must be lower than I wall, this time, I used the idea of dynamic planning, regardless of 3,721, first started according to I wall of the height of water, to a variable j = i+1, J has been moved to the end.

So there are several possibilities in the process of J moving to the end:

(1) met a wall than I wall to high, it is very good, then calculate to this position, the amount of water in this interval is our dynamic planning to calculate the amount of water, result added this value can be. Then J also do not have to look back, i=j,continue can be seen to help understand this situation, light green area = = Maxpoten, which is the amount of water left. When this value is added to result, I moves to J, and then continues to use J to look backwards.

(2) from the beginning to the end, J has not met the higher than I the wall, how to do? This time, the simplest way is, I direct continue. However, in this case, the values we have just counted are all white, and so the time complexity is certainly close to O (N2). So I did not realize this idea (although this idea is the simplest, the interview can be written directly);

(2) My idea is that the calculation is not in vain, how to do? Since the wall is higher than I or I do not find the wall, then we strive to find a lower than I the farthest wall.  If the worst case, did not find than I wall height or equal to the I wall, we can also use a little lower than the wall to compensate, just do the calculation will not be wasted. And!! Most importantly, after this calculation, I can jump directly to the position of the lower wall, time complexity is greatly reduced. The optimal situation can be close to O (n)!

Well, in this case, in the process of calculating the end of the j->, there are several variables that need to be calculated in real time:

Maxpoten, which represents the maximum possible water retention. When found than I wall high or equal to I wall, this value is the amount of water left, absolutely not wrong!

Lower, the representative did not find the ideal wall, but found a little lower than I wall wall, then in this case, the lower wall determines the amount of water left in this interval is not wrong!

Lowerpoten represents the amount of water left to be determined by the lower wall. Also, there is an arithmetic relationship between Lowerpoten and Maxpoten, and later we discuss the relationship and give the formula.

Is that enough? Let's take a look at the following diagram to help understand the possible problems in this case:

For example, after finding lower, the actual water storage should be lowerpoten, then lowerpoten how to calculate it. Maxpoten-(two wall height difference) * (two wall distance) = Lowerpoten? Light with abstract understanding, it is easy to get such a wrong formula, but look at the above picture on a glance, the details 2:lower the area behind, also need to subtract! What's the size of this area as it is labeled?

According to lower update mechanism, this area is in fact closely related to lower, we calculate in real time, in addition to the real-time calculation of Maxpoten, and then calculate the area, and then each time to find a new lower, the area is zeroed. In the end, we can get the area.

So, we also need a variable: lowerbehind.

So, Lowerpoten = Maxpoten-lowerbehind-(two wall height difference) * (two wall distance).

Is that OK? The answer is no, let's take a look at the following figure:

It can be clearly seen that the previous formula was wrong due to the presence of the orange-red block in the upper left corner: Lowerpoten = maxpoten-lowerbehind-(two wall height difference) * (two wall distance).

Because obviously, the details 3:maxpoten need to reduce the volume of water on the step and then reduce (the spacing between lower and step) * (two wall height difference) to get the correct answer.

Therefore, you need to consider how to calculate the amount of water on step.

Think about why step is produced, as you can see from the diagram, because the step height >=lower the height of the wall. Step determination seems simple: J from the i+1 bit began to go back, when the encounter is higher than lower and I close to the wall is step. But the idea of implementation is not good, because lower has not yet produced, how do I know the current wall is not a step. So, my train of thought is:

As long as the J Wall is adjacent to the I wall, the J wall is counted as step and then deposited in a list.

How to determine the immediate vicinity? Simple, give a Boolean next to the tag =true, as long as the current J wall is not 0 and the next mark is true, then the current J wall must be adjacent to the I wall. If the J wall is ==0, the adjacent flag is set to false.

After finalizing the lower, we then traverse the list and mark the last wall greater than lower from left to right as the right step wall. So Step1, Step2,. The amount of water added to the STEPN is the step in the water. At the same time, because the most right step wall has been calculated, then the gap between lower and this wall can be used to calculate lowerpoten.

In this, we come to the final formula:

Lowerpoten = Maxpoten-lowerbehind-stepwater-(two wall height difference) * (lower-right step wall)

Finally, the core point of the whole algorithm: lower, how to calculate?

First, the lower must be updated from the smallest to the maximum. Then lower first = 0, and then encounter larger than the current lower, lower on the update. But in doing so, there is a situation that cannot be solved. See:

According to the above description, the lower will be in the position of I + 1 when the descending sequence is encountered. This is obviously unreasonable. Because of this, you can keep water in this situation! So how should lower choose?

Obviously, lower will find at least one if the sequence is not descending. If the sequence is decreasing, lower must not find it.

So, lower update mechanism, in addition to the above mentioned, also need to add, details 4:j wall > J-1 wall case, lower began to update. Once there is a wall of J Wall >j-1, it is certainly not a descending sequence, then you can update the lower.

To this, the entire algorithm in the details are analyzed, in general, can write code.

"Show me the Code!!! 】

1 if(Height = =NULL|| Height.length = = 0)return0;2 3         intresult = 0;4         inti = 0;5          while(I <height.length) {6             //each time I move, a few variables go back to 07             intMaxpoten = 0;8             intLowerpoten = 0;9             intLower =-1;Ten             intLowerbehind = 0;//The total amount of water after lower, when necessary to lose, after each lower update, this value is updated to 0, and re-accumulate One             if(I < height.length-1 && Height[i] <= height[i + 1]) { Ai++; -                 Continue;//at present I is shorter than the latter one, direct continue, details 1 -             } theList<integer> Union =NewArraylist<integer> ();//preservation and I-wall continuous low wall -             BooleanIsunion =true; -             intj = i + 1; -              while(J <height.length) { +                 if(Height[j] >=Height[i]) { -                     //found a higher or higher than height[i], direct break; +                     //the current maxpoten is a temporary result, which can be added directly to result A                      Break; at                 } -                 if(Lower = =-1 && height[j] > Height[j-1]) { -                     //first appears in ascending order, lower updates to the first position, details 4 -Lower =J; -                 } -                 if(Height[j] = = 0) { inIsunion =false; -                 } toMaxpoten + = Height[i]-height[j];//every step is calculated Maxpoten +Lowerbehind + = Height[i]-height[j];//details 2, the area after lower needs to be calculated, when necessary to subtract -                 if(isunion) { theUnion.add (j);//at the end of the calculation, the union part also needs to be considered *                 } $                 if(Lower! =-1 && height[j] >=Height[lower]) {Panax Notoginsenglower = J;//update lower to the farthest, and height second only to height[i] location -                     //Lowerbehind from scratch after each update of lower theLowerbehind = 0; +                 } AJ + +; the             } +             //There are 2 possibilities: -             //(1) Break out, then maxpoten directly into the result, continue $             //(2) J traversed the entire array, indicating that Maxpoten is not available, then calculate Lowerpoten $             if(J = =height.length) { -                 //The instructions are normally traversed, and lower works. -                 //Calculate Lowerpoten the                 //first, the first steps of the storage of water, this part to distinguish between treatment -                 if(Lower = =-1) {Wuyi                     //Note also did not find lower, the explanation is a straight down step, cycle directly end the                      Break; -                 } Wu                 intStepwater = 0; -                 intK = 0; About                 if(Union.size () > 0) {//Calculate Stairs $                      while(K < Union.size () && Height[union.get (k)] >Height[lower]) { -Stepwater + = Height[i]-height[i + k + 1];//Detail 3, calculate the amount of water on step -k++; -                     } A                 } +                 //In addition, the Maxpoten should be cut off to lower, lower after the water can not be counted in. theLowerpoten = Maxpoten-stepwater-lowerbehind-(Height[i]-height[lower]) * (lower-(i +k)); -Result + =Lowerpoten; $i = lower;//I update to lower location the}Else { the                 //the description was break out. theResult + =Maxpoten; thei = j;//I move to the position of J -             } in         } the  the         returnresult; About}
Trap

The code is a bit long, but the efficiency is absolutely high, Leetcode ran all the use cases, only 5ms.

In terms of time complexity, I move directly to the lower or higher wall, since each time the lower is calculated or a wall that is higher than the I wall is found. So ideally the complexity of O (n). The average amortization is also relatively close to O (n).

Leetcode: Trapping Rain water

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.