Implement deposit, withdraw, and transfer in a class
Company: Capital One
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Quick Answer: This question evaluates a candidate's competence in concurrent programming, atomic state updates, and class-level account management for basic monetary operations.
Constraints
- 0 <= len(operations) <= 200000
- 1 <= amount <= 10^9 for deposit, withdraw, and transfer operations
- Account IDs are strings
- All operation names are valid and all amounts are positive integers
Examples
Input: [('deposit', 'A', 100), ('deposit', 'B', 40), ('transfer', 'A', 'B', 30), ('getBalance', 'A'), ('getBalance', 'B'), ('withdraw', 'B', 50), ('getBalance', 'B')]
Expected Output: [100, 40, True, 70, 70, True, 20]
Explanation: A gets 100, B gets 40, then 30 is transferred from A to B. After that B successfully withdraws 50, leaving balance 20.
Input: [('withdraw', 'X', 10), ('getBalance', 'X'), ('transfer', 'X', 'Y', 5), ('getBalance', 'Y')]
Expected Output: [False, 0, False, 0]
Explanation: Nonexistent accounts start with balance 0. The withdraw fails, the transfer also fails, and Y still has 0.
Input: [('deposit', 'alice', 50), ('deposit', 'bob', 20), ('transfer', 'alice', 'bob', 80), ('getBalance', 'alice'), ('getBalance', 'bob')]
Expected Output: [50, 20, False, 50, 20]
Explanation: Alice does not have enough money to transfer 80, so the transfer fails and both balances remain unchanged.
Input: [('deposit', 'z', 25), ('transfer', 'z', 'z', 10), ('getBalance', 'z'), ('transfer', 'z', 'z', 30), ('getBalance', 'z')]
Expected Output: [25, True, 25, False, 25]
Explanation: A self-transfer of 10 succeeds and leaves the balance unchanged. A self-transfer of 30 fails because the account only has 25.
Input: []
Expected Output: []
Explanation: No operations means no results.
Input: [('deposit', 'A', 10), ('transfer', 'A', 'C', 10), ('getBalance', 'A'), ('getBalance', 'C'), ('withdraw', 'C', 1), ('getBalance', 'C')]
Expected Output: [10, True, 0, 10, True, 9]
Explanation: C does not exist at first but is created implicitly by receiving a transfer. After withdrawing 1 from C, its balance becomes 9.
Solution
def solution(operations):
balances = {}
results = []
for op in operations:
action = op[0]
if action == 'deposit':
_, account_id, amount = op
balances[account_id] = balances.get(account_id, 0) + amount
results.append(balances[account_id])
elif action == 'withdraw':
_, account_id, amount = op
current = balances.get(account_id, 0)
if current < amount:
results.append(False)
else:
balances[account_id] = current - amount
results.append(True)
elif action == 'transfer':
_, from_id, to_id, amount = op
current = balances.get(from_id, 0)
if current < amount:
results.append(False)
else:
balances[from_id] = current - amount
balances[to_id] = balances.get(to_id, 0) + amount
results.append(True)
elif action == 'getBalance':
_, account_id = op
results.append(balances.get(account_id, 0))
else:
raise ValueError(f'Unknown operation: {action}')
return resultsTime complexity: O(q), where q is the number of operations. Space complexity: O(a), where a is the number of distinct accounts.
Hints
- Use a hash map (dictionary) from account ID to current balance so each operation can be processed in O(1) average time.
- For a transfer, first check whether the source account has enough money. Only update balances if the transfer can fully succeed.