Problem 2043

Abstract / Summary

Implement a simple bank account system that supports balance checking and depositing money.

Note

The full problem description, including helpful examples, can be found on LeetCode.

Python 2043.py

class Bank:
    def __init__(self, balance: List[int]):
        self.size = len(balance) # = n
        self.balance = [ 0 ] + balance

    def transfer(self, account1: int, account2: int, money: int) -> bool:
        if 1 <= account1 <= self.size and 1 <= account2 <= self.size: # and account1 != account2:
            if self.balance[account1] >= money:
                self.balance[account1] -= money
                self.balance[account2] += money
                return True
        return False

    def deposit(self, account: int, money: int) -> bool:
        if 1 <= account <= self.size:
            self.balance[account] += money
            return True
        return False

    def withdraw(self, account: int, money: int) -> bool:
        if 1 <= account <= self.size:
            if self.balance[account] >= money:
                self.balance[account] -= money
                return True
        return False
25 lines | 949 bytes | submitted January 14, 2024 | GitHub   9% comment ratio | tab size 4 | low complexity

Difficulty

This problem is ranked as
easy medium hard

and has an acceptance rate of about 70% (200k+ submissions).

Typical patterns to solve this problem:
  • Array
  • Design
  • Hash Table
  • Simulation
I solved 663 easy, 1250 medium and 309 hard problems

AI Disclaimer

Every single line of code was written by me, 100% from scratch, between August 2023 and August 2024.
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.

See this dedicated page for more details.
LeetCode profile | GitHub repo

Code Walkthrough

Overview

The provided Bank class models a simple banking system that maintains a collection of account balances and offers three fundamental operations: transferring money between accounts, depositing money into an account, and withdrawing money from an account. The implementation relies on a Python list to store balances, with an extra leading element to make the accounts 1-based, matching typical user expectations. Each public method validates input parameters before mutating the internal state, returning a Boolean flag that indicates success or failure.

Core Data Structure

The constructor receives a list of integer balances. It records the number of accounts in self.size and creates an internal list self.balance that begins with a dummy zero element followed by the supplied balances. This layout enables direct indexing using the account numbers supplied by callers.

def __init__(self, balance: List[int]):
    self.size = len(balance)          # total number of accounts
    self.balance = [0] + balance      # 1-based indexing for accounts

By storing balances in a contiguous list, the class achieves constant-time access for any account, which is essential for the high-frequency operations that a banking system typically performs.

Transfer Operation

The transfer method moves a specified amount of money from one account to another. It first checks that both account identifiers fall within the valid range (1 to self.size). The commented-out condition account1 != account2 indicates that self-transfers are implicitly allowed; the method will succeed as long as the source account has sufficient funds. After confirming that the source balance covers the requested amount, the method deducts the amount from the source and adds it to the destination, then returns True. If any validation fails, the method returns False.

def transfer(self, account1: int, account2: int, money: int) -> bool:
    if 1 <= account1 <= self.size and 1 <= account2 <= self.size:
        if self.balance[account1] >= money:
            self.balance[account1] -= money
            self.balance[account2] += money
            return True
    return False

The method’s early-exit pattern ensures that no state change occurs when the preconditions are not satisfied, preserving data integrity.

Deposit Operation

The deposit method adds a specified amount to a single account. It validates that the account number is within bounds and then increments the stored balance. The method always succeeds for a valid account, returning True; otherwise it returns False.

def deposit(self, account: int, money: int) -> bool:
    if 1 <= account <= self.size:
        self.balance[account] += money
        return True
    return False

Because the operation consists of a single list update, it executes in constant time.

Withdraw Operation

The withdraw method removes a specified amount from an account, provided the account exists and holds enough funds. The method first checks the account range, then verifies that the current balance meets or exceeds the withdrawal amount. If both checks pass, the balance is decreased and True is returned; otherwise the method returns False.

def withdraw(self, account: int, money: int) -> bool:
    if 1 <= account <= self.size:
        if self.balance[account] >= money:
            self.balance[account] -= money
            return True
    return False

The nested condition prevents an overdraft, ensuring that the internal state never reflects a negative balance.

Edge Cases Handled

The implementation explicitly guards against several boundary conditions.

When an account identifier is less than 1 or greater than the total number of accounts, each method rejects the request, preventing out-of-range list access.

For transfer and withdraw, the code checks that the source account’s balance is at least the requested amount, thereby avoiding underflow and guaranteeing that balances remain non-negative.

The deposit method does not impose an upper bound on the amount being added, allowing arbitrarily large deposits as long as the account identifier is valid.

Because the internal list is 1-based, the dummy zero element shields the real balances from accidental modification through an index of 0.

Self-transfers (where account1 equals account2) are permitted; the method will succeed if the source balance is sufficient, effectively leaving the balance unchanged after the debit and credit steps.

Performance Optimizations

The class leverages a plain Python list for balance storage, which provides O(1) random access and update. By pre-allocating the list with a leading dummy element, the code avoids the need to adjust indices on each operation, eliminating an extra arithmetic step per call.

All three public methods employ early returns after the first failing validation, which reduces unnecessary work and keeps the execution path short.

The absence of any auxiliary data structures or loops means that each operation runs with minimal overhead, making the class well-suited for scenarios that require a large number of rapid transactions.

The Boolean return values give callers immediate feedback without raising exceptions, allowing the surrounding code to decide how to handle failures without incurring the cost of exception handling.

written by openai gpt

ELI5 - Simplified Explanation

Imagine there is a big piggy bank that holds lots of little piggy banks inside it, all lined up in a row. This code is like being the person who takes care of all those little banks. When the bank starts, it looks at how much money is already inside each one and remembers those numbers.

The first part, called transfer, is like moving coins from one bank to another. If you have enough coins in the first bank, the helper takes some out of that one and puts them into the second one for you. It checks carefully to make sure both banks are real and that the first bank has enough money to share.

Depositing is like dropping a shiny coin into a specific piggy bank. The helper just finds the one you picked and slides the extra money right in so that the piggy bank is a little bit fuller than it was before.

Withdrawing is like taking coins out of your piggy bank to go buy a toy. The helper looks to make sure that the bank really exists and that it has enough coins currently sitting inside. If there is enough money, the helper takes the amount you want out of that bank and gives it to you.

written by google gemini

Code Quality

Several LLMs ranked my code quality on a scale from 1 (very poor) to 10 (outstanding):
n = 27 | median = 7 | μ = 6.07 | σ = 1.78

Complexity Analysis

not analyzed yet

Other Solutions

I wrote a basic crawler to find other solutions to that problem.
Obviously, I did that after I solved the problem myself.

In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.

And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.

(click on a column header to sort the table)
author
author solutions
www AlgoMonster C++ Python Java TS
WalkCCC C++ Python Java
leetcode.ca C++ Python Java Go Rust TS
Progiez C++ Python Java
github black-shadows C++
charles-wangkai Java
everthis JS
fsq C++
halfrost Go
JoshCrozier JS
lkwq007 Python
suxrobGM C#
trung-hn Python
varunu28 Java
withaarzoo C++
AlgoMonster C++, Python, Java, TypeScript
WalkCCC C++, Python, Java
leetcode.ca C++, Go, Java, Python, Rust, TypeScript
Progiez C++, Java, Python
black-shadows C++, C++
charles-wangkai Java
everthis JavaScript
fsq C++
halfrost Go
JoshCrozier JavaScript
lkwq007 Python
suxrobGM C#
trung-hn Python
varunu28 Java
withaarzoo C++
27 links | 15 authors | 8 languages

Videos

6 videos   did my crawler come up with invalid videos ? drop me a line.

Solved On The Same Day

5 solutions   January 14, 2024

Extra

There are a few extra pages giving you some insights into my setup:
  • Tech Stack - my development environment and tools
  • AI - how AI helped me create this website (NOT solving the problems)
  • Progress - progression over time
  • Quality - code quality