Skip to content

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