LeetCode 2043. 简易银行系统 虽说是一道普通题,但事实上其实是简单题,LeetCode 似乎特别喜欢把一些设计类题目写成普通题。
不是很想讲,但是踩了小坑,为了让我自己记住还是写一下吧。

题目

你的任务是为一个很受欢迎的银行设计一款程序,以自动化执行所有传入的交易(转账,存款和取款)。银行共有 n 个账户,编号从 1n 。每个账号的初始余额存储在一个下标从 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
输入:
["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 并不存在。

题解

这道题就是从头到尾把各种操作操作模拟一次就可以了,主要要注意以下几点:

  • 账户必须存在于 balance 数组中,也就是说如果这个 account 超出 balance 的 size 就不存在这个账户,所有的操作方法都需要检查一次是否存在。
  • withdraw() 中需要注意 money 不能够大于 balance[account-1] 。
  • 在题目中没有讲清楚关于 transfer() 这个方法的具体运作。应该来说是不允许 account1 和 account2 相同的,这样等于说是自己给自己转钱了;但题目答案允许了这种操作,导致我的提交错了两次,哭笑不得了属于是。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// 执行 212 ms 超越 65.13% 消耗 114.1 MB 超越 41.21%
class Bank {
vector<long long> balance_;
public:
Bank(vector<long long>& balance) {
balance_=balance;
}

bool transfer(int account1, int account2, long long money) {
if(account1==account2)
{
if(balance_[account1-1]>=money) //用两个判断来省略脱裤子放屁的步骤,实际提交中可以节省 50ms
return true;
else
return false;
}
if(withdraw(account1,money))
{
if(deposit(account2,money))
return true;
else
balance_[account1-1]+=money;
}
return false;
}

bool deposit(int account, long long money) {
if(account-1>balance_.size())
return false;
balance_[account-1]+=money;
return true;
}

bool withdraw(int account, long long money) {
if(account-1>balance_.size())
return false;
if(balance_[account-1]<money)
return false;
balance_[account-1]-=money;
return true;
}
};

PS

请各位写代码的时候切记仔细检查代码错漏,我就是因为忘记在本题中 account 忘记减 1 导致提交错误了两次,在实际开发中出现这样的问题将可能会引发非常严重的错误,要以此引以为戒。

另外是真的很想吐槽 LeetCode 这样的题目,弄出这样脱裤子放屁的东西。

另外应该还可以缩减程序的执行时长,如果有会的大佬希望能够指点迷津。

最后是日常惯例:

此解法非唯一解,且不一定是最好的解法,如果您有更好的解法,欢迎在评论区中提出。