Simulate pouring water onto a 1D terrain
Company: Airbnb
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Quick Answer: This question evaluates understanding of simulation of discrete physical processes, array manipulation, state tracking, and greedy/local-search movement rules, measuring algorithmic design and efficiency competencies.
Part 1: Render a 1D Terrain as ASCII
Constraints
- 0 <= len(heights) <= 200
- 0 <= heights[i] <= 200
- The total rendered output size will be small enough to fit in memory
Examples
Input: ([5, 4, 3, 2, 1, 3, 4, 0, 3, 4],)
Expected Output: ["+.........", "++....+..+", "+++..++.++", "++++.++.++", "+++++++.++", "++++++++++"]
Explanation: Matches the sample terrain, with `.` used for empty cells and an extra full base row at the bottom.
Input: ([1, 0, 2],)
Expected Output: ["..+", "+.+", "+++"]
Explanation: The tallest column has height 2, so there are 2 rows above the base.
Input: ([0, 0, 0],)
Expected Output: ["+++"]
Explanation: All columns have zero terrain height, so only the base row is shown.
Input: ([],)
Expected Output: []
Explanation: Empty input produces no rows.
Solution
def solution(heights):
if not heights:
return []
n = len(heights)
max_h = max(heights)
rows = []
for level in range(max_h, 0, -1):
row = []
for h in heights:
row.append('+' if h >= level else '.')
rows.append(''.join(row))
rows.append('+' * n)
return rowsTime complexity: O(n * H), where n is the number of columns and H is the maximum height. Space complexity: O(n * H) including the returned output, or O(1) auxiliary space aside from output.
Hints
- Build the picture one row at a time, starting from the maximum terrain height down to 1.
- For a given row level `L`, column `i` contains `'+'` if `heights[i] >= L`; otherwise it contains `'.'`.
Part 2: Pour Water on a 1D Terrain and Render the Final State
Constraints
- 1 <= len(heights) <= 200
- 0 <= heights[i] <= 100
- 0 <= waterAmount <= 200
- 0 <= column < len(heights)
- The total rendered output size will be small enough to fit in memory
Examples
Input: ([2, 1, 2, 1, 2], 1, 2)
Expected Output: ["+W+.+", "+++++", "+++++"]
Explanation: Both sides have a lower reachable column, so the water must prefer the left side first and settle at index 1.
Input: ([3, 1, 3], 2, 0)
Expected Output: ["+W+", "+W+", "+++", "+++"]
Explanation: There is no left side, so water falls to the right valley twice, stacking there.
Input: ([1, 1, 1], 1, 1)
Expected Output: [".W.", "+++", "+++"]
Explanation: Neither side is strictly lower, so the water stays at the source column.
Input: ([3, 1, 1, 3], 1, 3)
Expected Output: ["+..+", "+W.+", "++++", "++++"]
Explanation: The left scan reaches two equally low positions. The water settles at the leftmost of those lowest positions.
Input: ([0], 3, 0)
Expected Output: ["W", "W", "W", "+"]
Explanation: Single-column edge case: all water stacks in the only column above the base.
Solution
def solution(heights, waterAmount, column):
if not heights:
return []
n = len(heights)
water = [0] * n
def eff(i):
return heights[i] + water[i]
for _ in range(waterAmount):
start_eff = eff(column)
# Try left first.
best = column
min_eff = start_eff
i = column
while i > 0 and eff(i - 1) <= eff(i):
i -= 1
current_eff = eff(i)
if current_eff < min_eff:
min_eff = current_eff
best = i
elif current_eff == min_eff:
best = i
if min_eff < start_eff:
water[best] += 1
continue
# If left fails, try right.
best = column
min_eff = start_eff
i = column
while i < n - 1 and eff(i + 1) <= eff(i):
i += 1
current_eff = eff(i)
if current_eff < min_eff:
min_eff = current_eff
best = i
elif current_eff == min_eff:
best = i
if min_eff < start_eff:
water[best] += 1
else:
water[column] += 1
final_height = max(h + w for h, w in zip(heights, water))
rows = []
for level in range(final_height, 0, -1):
row = []
for h, w in zip(heights, water):
if level <= h:
row.append('+')
elif level <= h + w:
row.append('W')
else:
row.append('.')
rows.append(''.join(row))
rows.append('+' * n)
return rowsTime complexity: O(waterAmount * n + n * H), where H is the final maximum of `heights[i] + water[i]`. Space complexity: O(n * H) including the returned output, plus O(n) auxiliary space for the water array.
Hints
- Keep a separate `water` array and always compare columns using `heights[i] + water[i]`.
- When scanning left or right, stop as soon as the next step would go uphill. While scanning, remember the lowest reachable effective height; on ties, prefer the direction you are scanning toward.