堂哥 40.5岁,今年被裁员了,赔偿金54.6万,被裁后他找了半年的工作,都嫌弃他年龄大,工资比以前少大半不够养家。他问我咋办
刚看到个贴子,说网友堂哥40.5岁,今年被裁,拿了54.6万赔偿,结果找了半年工作,不是嫌他年龄大,就是工资只有以前一半,养家都吃力,他问“我咋办”。
网友们回复我看了看,有说让他拿钱躺平的,有劝回老家创业的,还有让他咬牙等“更合适机会”的。怎么说呢,这几种我都不太认同。
54.6万,说多不多,说少也不少,本质上是“缓冲期的钱”,不是一劳永逸的钱,用来赌躺平或盲目创业,风险都太大。
40多岁被裁确实难,但不是死局。放下面子,当一次“重新上路的新手”,比在原地自怨自艾强多了。
面试题:银行账户概要
昨天晚上十一点多,我在手机上查信用卡账单,看到一堆“+100”“-35.5”“-276”……脑子里蹦出来的第一个想法就是:要是后台那哥们儿算法写错了,我现在看到的余额,很可能就不是余额,是惊喜了。
其实“银行账户概要”这个题,大白话就是: 给你一堆流水,帮我算出每个账户现在还剩多少钱,再把满足条件的账户挑出来。 LeetCode 上有一道数据库题叫 Bank Account Summary II,本质干的也是这件事,只不过那边用 SQL,我们这边用 Java 写一个算法版就行了。
咱别管官方描述了,就按工作里的真实需求来想:
有很多用户,每个用户有一个账号 account,比如 1001、1002 有一张交易流水表,每条流水包含:哪个账号、金额多少,正数代表存钱,负数代表取钱
现在要做两件事:
把所有流水按账号汇总,算出每个账号的当前余额 再根据条件过滤一下,比如余额大于 10000 的用户,导出来让运营去“关怀”一波
核心动作其实就两个字:累加。
用最顺手的方式想一遍思路
假设你是出纳,只有一张白纸,你会怎么记?
很自然吧:来一条流水,就在那个人名下面加加减减。 翻译成代码,就是拿一个 Map<String, Long>:
key:账号 value:当前为止的余额
扫描一遍交易列表:
如果这个账号第一次出现,就先当成 0 金额加上去,更新 map 里的余额
一趟扫完,map 里就有了所有账号的余额,再从里面挑余额大于 10000 的就行。
时间复杂度:
扫一遍流水是 O(n) map 插入和查询平均 O(1) 整体就是 O(n),空间是 O(账户数),在实际系统里也是常规写法。
为了让代码好读一点,我偷懒写个最简单的 Transaction 类,你也可以直接用 record 或者 Map,随你:
publicclassBankAccountSummary{
// 一条交易流水
staticclassTransaction{
String account; // 账号
long amount; // 正数存,负数取
publicTransaction(String account, long amount){
this.account = account;
this.amount = amount;
}
}
/**
* 计算每个账号的余额
*/
publicstatic Map<String, Long> calcBalance(List<Transaction> list){
Map<String, Long> balanceMap = new HashMap<>();
for (Transaction tx : list) {
long old = balanceMap.getOrDefault(tx.account, 0L);
long now = old + tx.amount;
balanceMap.put(tx.account, now);
}
return balanceMap;
}
/**
* 过滤出余额大于 limit 的账号
*/
publicstatic Map<String, Long> filterByLimit(Map<String, Long> balances, long limit){
Map<String, Long> result = new HashMap<>();
for (Map.Entry<String, Long> entry : balances.entrySet()) {
if (entry.getValue() > limit) {
result.put(entry.getKey(), entry.getValue());
}
}
return result;
}
publicstaticvoidmain(String[] args){
List<Transaction> list = Arrays.asList(
new Transaction("1001", 5000),
new Transaction("1002", 8000),
new Transaction("1001", -1000),
new Transaction("1003", 20000),
new Transaction("1002", 4000)
);
// 1. 汇总余额
Map<String, Long> balances = calcBalance(list);
// 2. 过滤出余额大于 10000 的账号
Map<String, Long> rich = filterByLimit(balances, 10000);
// 3. 打印一下结果
for (Map.Entry<String, Long> e : rich.entrySet()) {
System.out.println("account=" + e.getKey() + ", balance=" + e.getValue());
}
}
}
你脑补一下这段 main 的输出:
1001:5000 - 1000 = 4000,不够 10000,被过滤掉 1002:8000 + 4000 = 12000,留下 1003:20000,肯定留下
所以控制台里大概就两行账号 1002、1003。
行了,先到这儿,我去翻翻我那张信用卡账单,看看是不是也该写个程序帮我算算钱花哪儿去了…
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html