Medium

题目描述

你需要为一家受欢迎的银行编写一个程序,该程序将自动处理所有传入的交易(转账、存款和取款)。该银行有 n 个账户,编号从 1 到 n。每个账户的初始余额存储在一个下标从 0 开始的整数数组 balance 中,其中第 (i + 1) 个账户的初始余额为 balance[i]。

执行所有有效的交易。如果满足以下全部条件,则交易有效:

  • 给定的账户编号在 1 和 n 之间,且
  • 取款或者转账的金额小于或者等于账户余额。

请你实现 Bank 类:

  • Bank(long[] balance) 使用下标从 0 开始的整数数组 balance 对对象进行初始化。
  • boolean transfer(int account1, int account2, long money) 从编号为 account1 的账户向编号为 account2 的账户转账 money 美元。如果交易成功,返回 true ,否则,返回 false 。
  • boolean deposit(int account, long money) 向编号为 account 的账户存入 money 美元。如果交易成功,返回 true ;否则,返回 false 。
  • boolean withdraw(int account, long money) 从编号为 account 的账户取款 money 美元。如果交易成功,返回 true ;否则,返回 false 。

示例 1:

输入:
["Bank", "withdraw", "transfer", "deposit", "transfer", "withdraw"]
[[[10, 100, 20, 50, 30]], [3, 10], [5, 1, 20], [5, 20], [3, 4, 15], [10, 50]]
输出:
[null, true, true, true, false, false]

解释:
Bank bank = new Bank([10, 100, 20, 50, 30]);
bank.withdraw(3, 10);    // 返回 true ,账户 3 的余额是 $20 ,所以可以取款 $10 。
                         // 账户 3 余额为 $20 - $10 = $10 。
bank.transfer(5, 1, 20); // 返回 true ,账户 5 的余额是 $30 ,所以可以转账 $20 。
                         // 账户 5 的余额为 $30 - $20 = $10 ,账户 1 的余额为 $10 + $20 = $30 。
bank.deposit(5, 20);     // 返回 true ,可以向账户 5 存入 $20 。
                         // 账户 5 的余额为 $10 + $20 = $30 。
bank.transfer(3, 4, 15); // 返回 false ,账户 3 的当前余额是 $10 ,
                         // 所以无法转账 $15 。
bank.withdraw(10, 50);   // 返回 false ,交易无效,因为账户 10 并不存在。

提示:

  • n == balance.length
  • 1 <= n, account, account1, account2 <= 10^5
  • 0 <= balance[i], money <= 10^12
  • transferdepositwithdraw 三个函数,每个最多调用 10^4

解题思路

这是一道银行系统模拟题,需要实现三个基本的银行操作:转账、存款和取款。

核心思路:

  1. 账户验证:所有操作前都需要验证账户编号是否有效(在 1 到 n 范围内)
  2. 余额检查:对于取款和转账操作,需要确保账户余额足够
  3. 原子操作:转账操作需要同时修改两个账户的余额

具体实现:

  • 使用一个辅助函数 isValidAccount 来验证账户编号的有效性
  • withdraw 操作:验证账户有效性和余额充足性,然后减少账户余额
  • deposit 操作:验证账户有效性,然后增加账户余额
  • transfer 操作:验证两个账户的有效性和源账户余额充足性,然后执行转账

注意事项:

  • 账户编号从 1 开始,但数组索引从 0 开始,需要进行转换
  • 需要使用 long long 类型处理大额金额
  • 所有操作都要先验证有效性,失败时不修改账户余额

这个解法时间复杂度为 O(1),空间复杂度为 O(n),其中 n 是账户数量。

代码实现

class Bank {
private:
    vector<long long> accounts;
    
    bool isValidAccount(int account) {
        return account >= 1 && account <= accounts.size();
    }
    
public:
    Bank(vector<long long>& balance) {
        accounts = balance;
    }
    
    bool transfer(int account1, int account2, long long money) {
        if (!isValidAccount(account1) || !isValidAccount(account2)) {
            return false;
        }
        if (accounts[account1 - 1] < money) {
            return false;
        }
        accounts[account1 - 1] -= money;
        accounts[account2 - 1] += money;
        return true;
    }
    
    bool deposit(int account, long long money) {
        if (!isValidAccount(account)) {
            return false;
        }
        accounts[account - 1] += money;
        return true;
    }
    
    bool withdraw(int account, long long money) {
        if (!isValidAccount(account)) {
            return false;
        }
        if (accounts[account - 1] < money) {
            return false;
        }
        accounts[account - 1] -= money;
        return true;
    }
};
class Bank:

    def __init__(self, balance: List[int]):
        self.accounts = balance
    
    def _is_valid_account(self, account):
        return 1 <= account <= len(self.accounts)

    def transfer(self, account1: int, account2: int, money: int) -> bool:
        if not self._is_valid_account(account1) or not self._is_valid_account(account2):
            return False
        if self.accounts[account1 - 1] < money:
            return False
        self.accounts[account1 - 1] -= money
        self.accounts[account2 - 1] += money
        return True

    def deposit(self, account: int, money: int) -> bool:
        if not self._is_valid_account(account):
            return False
        self.accounts[account - 1] += money
        return True

    def withdraw(self, account: int, money: int) -> bool:
        if not self._is_valid_account(account):
            return False
        if self.accounts[account - 1] < money:
            return False
        self.accounts[account - 1] -= money
        return True
public class Bank {
    private long[] accounts;
    
    private bool IsValidAccount(int account) {
        return account >= 1 && account <= accounts.Length;
    }

    public Bank(long[] balance) {
        accounts = new long[balance.Length];
        Array.Copy(balance, accounts, balance.Length);
    }
    
    public bool Transfer(int account1, int account2, long money) {
        if (!IsValidAccount(account1) || !IsValidAccount(account2)) {
            return false;
        }
        if (accounts[account1 - 1] < money) {
            return false;
        }
        accounts[account1 - 1] -= money;
        accounts[account2 - 1] += money;
        return true;
    }
    
    public bool Deposit(int account, long money) {
        if (!IsValidAccount(account)) {
            return false;
        }
        accounts[account - 1] += money;
        return true;
    }
    
    public bool Withdraw(int account, long money) {
        if (!IsValidAccount(account)) {
            return false;
        }
        if (accounts[account - 1] < money) {
            return false;
        }
        accounts[account - 1] -= money;
        return true;
    }
}
var Bank = function(balance) {
    this.accounts = [...balance];
};

Bank.prototype.isValidAccount = function(account) {
    return account >= 1 && account <= this.accounts.length;
};

Bank.prototype.transfer = function(account1, account2, money) {
    if (!this.isValidAccount(account1) || !this.isValidAccount(account2)) {
        return false;
    }
    if (this.accounts[account1 - 1] < money) {
        return false;
    }
    this.accounts[account1 - 1] -= money;
    this.accounts[account2 - 1] += money;
    return true;
};

Bank.prototype.deposit = function(account, money) {
    if (!this.isValidAccount(account)) {
        return false;
    }
    this.accounts[account - 1] += money;
    return true;
};

Bank.prototype.withdraw = function(account, money) {
    if (!this.isValidAccount(account)) {
        return false;
    }
    if (this.accounts[account - 1] < money) {
        return false;
    }
    this.accounts[account - 1] -= money;
    return true;
};

复杂度分析

操作时间复杂度空间复杂度
初始化O(n)O(n)
transferO(1)O(1)
depositO(1)O(1)
withdrawO(1)O(1)

其中 n 为银行账户数量。所有操作都是常数时间复杂度,空间复杂度主要用于存储账户余额数组。

相关题目