程序员老鬼

堂哥 40.5岁,今年被裁员了,赔偿金54.6万,被裁后他找了半年的工作,都嫌弃他年龄大,工资比以前少大半不够养家。他问我咋办

刚看到个贴子,说网友堂哥40.5岁,今年被裁,拿了54.6万赔偿,结果找了半年工作,不是嫌他年龄大,就是工资只有以前一半,养家都吃力,他问“我咋办”。

Image

网友们回复我看了看,有说让他拿钱躺平的,有劝回老家创业的,还有让他咬牙等“更合适机会”的。怎么说呢,这几种我都不太认同。

54.6万,说多不多,说少也不少,本质上是“缓冲期的钱”,不是一劳永逸的钱,用来赌躺平或盲目创业,风险都太大。

40多岁被裁确实难,但不是死局。放下面子,当一次“重新上路的新手”,比在原地自怨自艾强多了。

面试题:银行账户概要

昨天晚上十一点多,我在手机上查信用卡账单,看到一堆“+100”“-35.5”“-276”……脑子里蹦出来的第一个想法就是:要是后台那哥们儿算法写错了,我现在看到的余额,很可能就不是余额,是惊喜了。

其实“银行账户概要”这个题,大白话就是: 给你一堆流水,帮我算出每个账户现在还剩多少钱,再把满足条件的账户挑出来。 LeetCode 上有一道数据库题叫 Bank Account Summary II,本质干的也是这件事,只不过那边用 SQL,我们这边用 Java 写一个算法版就行了。

咱别管官方描述了,就按工作里的真实需求来想:

  • 有很多用户,每个用户有一个账号 account,比如 1001、1002
  • 有一张交易流水表,每条流水包含:哪个账号、金额多少,正数代表存钱,负数代表取钱

现在要做两件事:

  1. 把所有流水按账号汇总,算出每个账号的当前余额
  2. 再根据条件过滤一下,比如余额大于 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

最后给大家分享一份不错的副业资料,点击下方公众号,回复关键字: 副业 领,也可以链接我微信:hls404