You are given the following to describe how much water pouring will affect a terrain. The terrain is represented as an array of non-negative integers, where each non-negative integer represents the height of a terrain block.
We will pour K
units of water onto the terrain. The water will spread to the left and right only if there is a block lower than where the water is poured. We start pouring water at index index
.
Return the array representing the terrain after pouring K
units of water.
Example 1:
Input: heights = [2,1,1,2,1,2,2], K = 4, index = 3
Output: [2,2,2,3,2,2,2]
Explanation:
The first drop of water lands at index 3:
[2,1,1,2,1,2,2]
&x2192;[2,1,1,3,1,2,2].
The next drop of water lands at index 3:
[2,1,1,3,1,2,2]
&x2192;[2,1,1,4,1,2,2].
The next drop of water lands at index 3:
[2,1,1,4,1,2,2]
&x2192;[2,1,2,4,1,2,2].
The next drop of water lands at index 2:
[2,1,2,4,1,2,2]
&x2192;[2,1,3,4,1,2,2].
Example 2:
Input: heights = [1,2,3,4,3,2,1,2,3,2,1], K = 5, index = 5
Output: [1,2,3,4,3,3,2,2,3,2,1]
Example 3:
Input: heights = [1,2,2,2,2,1,1,2,1,2,1], K = 2, index = 5
Output: [1,2,2,2,2,2,2,2,1,2,1]
Constraints:
1 <= heights.length <= 100
0 <= heights[i] <= 100
1 <= K <= 1000
0 <= index < heights.length
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to pouring water involves simulating the pouring process step by step. We'll directly simulate where the water flows after each drop is poured. This continues until all water has been poured.
Here's how the algorithm would work step-by-step:
def pour_water(heights, water_amount, pour_location):
heights = list(heights)
for _ in range(water_amount):
current_location = pour_location
# Find the lowest adjacent index to move water to
while True:
left_index = current_location - 1
right_index = current_location + 1
# Check if left neighbor exists and is lower
if left_index >= 0 and heights[left_index] < heights[current_location]:
# Check if right neighbor is also lower than left neighbor, if so, skip to right
if right_index < len(heights) and heights[right_index] < heights[left_index]:
break
else:
current_location = left_index
continue
# Check if right neighbor exists and is lower
if right_index < len(heights) and heights[right_index] < heights[current_location]:
current_location = right_index
continue
# No lower neighbor, water stays at the current location
break
# Increase the height at the final location
heights[current_location] += 1
return heights
The problem asks us to simulate pouring water onto terrain represented by different heights. The trick is to efficiently figure out where the water will flow, instead of simulating every single drop individually. We'll focus on finding the lowest point near where we pour the water, and directing the water there.
Here's how the algorithm would work step-by-step:
def pour_water(heights, water_amount, pour_location): current_heights = heights[:] for _ in range(water_amount): current_location = pour_location # Try to move water to the left.
left_location = current_location while left_location > 0 and current_heights[left_location - 1] <= current_heights[current_location]: if current_heights[left_location - 1] < current_heights[current_location]: current_location = left_location - 1
else:
left_location -= 1
# If water didn't move left, try to move to the right.
if current_location == pour_location:
right_location = current_location
while right_location < len(current_heights) - 1 and current_heights[right_location + 1] <= current_heights[current_location]: if current_heights[right_location + 1] < current_heights[current_location]: current_location = right_location + 1 else: right_location += 1 # Water couldn't move; increase height at pour location
if current_location == pour_location: current_heights[pour_location] += 1 # Move water to the lowest spot found.
else: current_heights[current_location] += 1 return current_heights
Case | How to Handle |
---|---|
Empty heights array | Return the original heights array unchanged if it's empty, as no water can be poured. |
K is negative or larger than the array size | If K is invalid (negative or out of bounds), handle it by clamping it within the valid range [0, heights.length -1]. |
Drops is zero | If drops is zero, return the original array immediately, as no water needs to be poured. |
Heights array contains very large values | Ensure integer overflow is handled during water accumulation by using a data type with sufficient range like long. |
Heights array contains all identical values | The water should distribute evenly to the left or right depending on which direction offers the lowest point. |
K is at the left or right edge of the array | The pouring will only distribute to the right or left, respectively. |
Heights array contains negative values | Ensure negative height values are handled correctly, by considering them in the water distribution logic. |
K is at the location of the tallest index | Water should flow left or right depending on which side has the shortest height. |