Water collected between towers

后端 未结 26 1095
无人共我
无人共我 2020-12-22 16:51

I recently came across an interview question asked by Amazon and I am not able to find an optimized algorithm to solve this question:

You are given an input array wh

26条回答
  •  -上瘾入骨i
    2020-12-22 17:36

    O(n) solution in Java, single pass

    Another implementation in Java, finding the water collected in a single pass through the list. I scanned the other answers but didn't see any that were obviously using my solution.

    1. Find the first "peak" by looping through the list until the tower height stops increasing. All water before this will not be collected (drain off to the left).
    2. For all subsequent towers:
      • If the height of the subsequent tower decreases or stays the same, add water to a "potential collection" bucket, equal to the difference between the tower height and the previous max tower height.
      • If the height of the subsequent tower increases, we collect water from the previous bucket (subtract from the "potential collection" bucket and add to the collected bucket) and also add water to the potential bucket equal to the difference between the tower height and the previous max tower height.
      • If we find a new max tower, then all the "potential water" is moved into the collected bucket and this becomes the new max tower height.

    In the example above, with input: [5,3,7,2,6,4,5,9,1,2], the solution works as follows:

    • 5: Finds 5 as the first peak
    • 3: Adds 2 to the potential bucket (5-3)

      collected = 0, potential = 2

    • 7: New max, moves all potential water to the collected bucket

      collected = 2, potential = 0

    • 2: Adds 5 to the potential bucket (7-2)

      collected = 2, potential = 5

    • 6: Moves 4 to the collected bucket and adds 1 to the potential bucket (6-2, 7-6)

      collected = 6, potential = 2

    • 4: Adds 2 to the potential bucket (6-4)

      collected = 6, potential = 4

    • 5: Moves 1 to the collected bucket and adds 2 to the potential bucket (5-4, 7-5)

      collected = 7, potential = 6

    • 9: New max, moves all potential water to the collected bucket

      collected = 13, potential = 0

    • 1: Adds 8 to the potential bucket (9-1)

      collected = 13, potential = 8

    • 2: Moves 1 to the collected bucket and adds 7 to the potential bucket (2-1, 9-2)

      collected = 14, potential = 15

    After running through the list once, collected water has been measured.

    public static int answer(int[] list) {
        int maxHeight = 0;
        int previousHeight = 0;
        int previousHeightIndex = 0;
        int coll = 0;
        int temp = 0;
    
        // find the first peak (all water before will not be collected)
        while(list[previousHeightIndex] > maxHeight) {
            maxHeight = list[previousHeightIndex];
            previousHeightIndex++;
            if(previousHeightIndex==list.length)            // in case of stairs (no water collected)
                return coll;
            else
                previousHeight = list[previousHeightIndex];
        }
    
        for(int i = previousHeightIndex; i= maxHeight) {      // collect all temp water
                coll += temp;
                temp = 0;
                maxHeight = list[i];        // new max height
            }
            else {
                temp += maxHeight - list[i];
                if(list[i] > previousHeight) {  // we went up... collect some water
                    int collWater = (i-previousHeightIndex)*(list[i]-previousHeight);
                    coll += collWater;
                    temp -= collWater;
                }
            }
    
            // previousHeight only changes if consecutive towers are not same height
            if(list[i] != previousHeight) {
                previousHeight = list[i];
                previousHeightIndex = i;
            }
        }
        return coll;
    }
    

提交回复
热议问题