Carrying Forward
A medium Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- medium
- Seniority
- L3
Problem
Given the daily deposits to an account in the order they landed, return the balance standing after each one, for a running-balance chart on a dashboard.
The total grows with every row.
Example 1
Input:
deposits = [1,2,3,4]
Output:
[1,3,6,10]
Example 2
Input:
deposits = []
Output:
[]
Worked solution and explanation
What this really is
This is a prefix sum wearing a ledger costume. The skill being probed: can you carry state across a single pass instead of recomputing it? Anyone can produce the right numbers. The trap is reaching for sum(deposits[:i+1]) at each position, which re-adds the same prefix over and over and turns an O(n) walk into O(n^2) that quietly dies on a 10k-element ledger. Get the accumulator right and the empty list falls out for free, no special case.
Break down the requirements
Step 1: Maintain a running total in one pass
Initialize total = 0, loop over deposits, update total += amount, append total to the output list. Single pass, no nested loops. The naive O(n^2) is sum(deposits[:i+1]) for each i, which recomputes the same prefixes repeatedly and is a red flag at any level above junior.
Step 2: Preallocate or append; both are O(n)
Python list.append has amortized O(1) cost, so the append-in-loop version hits O(n) total. Preallocating [0] * len(deposits) and assigning by index is the same asymptotic cost but uses more code. Append is cleaner and equally fast.
Step 3: Return [] for empty input with no branch
Looping over [] produces no iterations, the output list stays [], the return value is []. No 'if not deposits: return []' branch needed. Writing it is a tell that you do not trust the loop.
The solution
def running_total(deposits):
balances = []
total = 0
for amount in deposits:
total += amount
balances.append(total)
return balancesCommon follow-up questions
- Rewrite this using itertools.accumulate. (from itertools import accumulate; return list(accumulate(deposits)). Discuss why it is slightly faster (C implementation) and when to use the explicit loop (custom behavior, early exit).)
- How would you support a running product instead of a running total? (accumulate(deposits, operator.mul) or a manual loop with total *= amount and initial total = 1. Mention that empty input must return [] (not [1]) to match the additive contract.)
- How would you compute the running total over a 10 GB file of numbers? (stream line by line, accumulate as you go, write output line by line; never materialize the full list. Mention numpy.cumsum for in-memory numeric arrays.)