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.length1 <= n, account, account1, account2 <= 10^50 <= balance[i], money <= 10^12transfer、deposit、withdraw三个函数,每个最多调用10^4次
解题思路
这是一道银行系统模拟题,需要实现三个基本的银行操作:转账、存款和取款。
核心思路:
- 账户验证:所有操作前都需要验证账户编号是否有效(在 1 到 n 范围内)
- 余额检查:对于取款和转账操作,需要确保账户余额足够
- 原子操作:转账操作需要同时修改两个账户的余额
具体实现:
- 使用一个辅助函数
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) |
| transfer | O(1) | O(1) |
| deposit | O(1) | O(1) |
| withdraw | O(1) | O(1) |
其中 n 为银行账户数量。所有操作都是常数时间复杂度,空间复杂度主要用于存储账户余额数组。
相关题目
- . Design an ATM Machine (Medium)