2043. Simple Bank System
On LeetCode ->Problem¶
Implement a bank with accounts numbered from 1 to n. Deposits, withdrawals, and transfers return whether they succeeded; invalid account numbers or insufficient funds must leave balances unchanged.
Start: [10, 20]
transfer(2, 1, 5) -> True balances: [15, 15]
withdraw(2, 20) -> False balances: [15, 15]
Key trick¶
Check every account and the source balance before changing either balance.
Trap¶
Account numbers are 1-indexed, but balances are 0-indexed. A failed transfer must not partially update the accounts.
Why is it interesting?¶
It tests whether you preserve state correctly across a sequence of operations.
Python solution¶
class Bank:
def __init__(self, balance: list[int]):
self.balance = balance[:]
def _valid(self, account: int) -> bool:
return 1 <= account <= len(self.balance)
def transfer(self, account1: int, account2: int, money: int) -> bool:
# Validate both accounts and available funds before changing state.
if not self._valid(account1) or not self._valid(account2):
return False
if self.balance[account1 - 1] < money:
return False
self.balance[account1 - 1] -= money
self.balance[account2 - 1] += money
return True
def deposit(self, account: int, money: int) -> bool:
if not self._valid(account):
return False
self.balance[account - 1] += money
return True
def withdraw(self, account: int, money: int) -> bool:
if not self._valid(account) or self.balance[account - 1] < money:
return False
self.balance[account - 1] -= money
return True
Initialization takes \(O(n)\) time and space for the copy. Each transaction takes \(O(1)\) time and extra space.
Comment on my solution¶
Your solution is correct. The optional money argument lets _valid handle both account existence and sufficient funds, including a withdrawal of zero. Copying balance also prevents transactions from modifying the caller's list.
class Bank:
def __init__(self, balance: list[int]):
self.balance = balance[:]
def _valid(self, account: int, money: int | None = None):
if account < 1 or account > len(self.balance):
return False
if money is not None and self.balance[account - 1] < money:
return False
return True
def transfer(self, account1: int, account2: int, money: int) -> bool:
if not self._valid(account1, money) or not self._valid(account2):
return False
self.balance[account1 - 1] -= money
self.balance[account2 - 1] += money
return True
def deposit(self, account: int, money: int) -> bool:
if not self._valid(account):
return False
self.balance[account - 1] += money
return True
def withdraw(self, account: int, money: int) -> bool:
if not self._valid(account, money):
return False
self.balance[account - 1] -= money
return True