程序员老鬼

面试官:面试结果半年内会通知你。。

昨天晚上在公司楼下抽烟,隔壁组小王跟我吐槽,说他遇到一个“传奇”面试官,直接让他手撕B+树,还要逐字母背 map 遍历代码🤯。我当时还问他,是不是公司想招个算法竞赛冠军?结果更离谱的在后面——反问环节他问面试结果多久出来,面试官面不改色地说:“半年内会通知你。”

Image

半年啊兄弟,这不就是异步+无限延迟么😂。 作为干了十几年的老程序员,这种面试我见多了,基本就是不想要你还得保持“面试礼貌”,相当于HTTP返回个 202 Accepted,但其实后台早 drop table 了。

真心建议大家,碰到这种面试流程奇葩的公司,直接Ctrl+C退出,别浪费CPU和内存资源。毕竟我们调试Bug都不需要等半年,面试结果也不该是长轮询啊…【备注:文末可领最新资料】

算法题:根据字符出现频率排序

昨晚十一点多,在公司楼下吹风…脑子里还在想那个面试题,嘿就是“按字符出现频率排序”。有人在群里问我咋写,我当时手一抖就敲了个 Java 版本,嗯…现在把思路捋顺给你们,口水话多点,别介意哈。

给你一个字符串,比如 "treee",把出现次数多的字符排前面,次数一样就按字母顺序或者保持原顺序也行(面试官会说清…没有就自己定个规矩)。最后要返回排完的字符串,比如 "eeert" 这种。核心就是两个词:计数、排序。就这俩。

思路非常直白:先数一数每个字符出现了几次,然后把它们按次数从大到小“倒出来”。用 HashMap 计数,用 PriorityQueue(大根堆)排序。为了不扯皮,我顺手定了个平手规则:次数相同就按字符的自然顺序排('a' 在 'b' 前)。

import java.util.*;

publicclassFreqSort{
// 次数多的在前,次数相同按字符升序
publicstatic String frequencySort(String s){
if (s == null || s.length() <= 1) return s;

        Map<Character, Integer> cnt = new HashMap<>();
for (char c : s.toCharArray()) {
            cnt.put(c, cnt.getOrDefault(c, 0) + 1);
        }

        PriorityQueue<Map.Entry<Character,Integer>> pq =
new PriorityQueue<>((a, b) -> {
int x = b.getValue() - a.getValue();
if (x != 0) return x;
return a.getKey() - b.getKey();
                });

        pq.addAll(cnt.entrySet());

        StringBuilder sb = new StringBuilder(s.length());
while (!pq.isEmpty()) {
            Map.Entry<Character,Integer> e = pq.poll();
for (int i = 0; i < e.getValue(); i++) sb.append(e.getKey());
        }
return sb.toString();
    }

// 小测一下
publicstaticvoidmain(String[] args){
        System.out.println(frequencySort("treee"));   // eeert
        System.out.println(frequencySort("Aabb"));    // bbAa 或 bbaA 取决于规则
    }
}

你看,代码就…挺像回事的对吧。HashMap 计数是 O(n),堆里最多放 k 个不同字符,弹出的时候总复杂度大概 O(n log k)。一般字符串字符种类不多,跑得顺滑。哦对了,这里 char 就按 UTF-16 单元处理,遇到表情那种代理对会被拆开——真上生产要处理 Unicode 码点可以改用 codePoints()。

如果你懒得用堆,知道最大频次最多也就 n,那可以搞个“桶”:按频次下标建一个 List<Character>[] buckets,把同频的字符塞到同一个桶里,然后从高频桶往低频桶倒着拼接。这样复杂度能到 O(n)。不过嘛…写起来多两行,也就那回事。

1)平手规则一定说清,不然评测用例跟你想的不一样就尴尬。 2)大小写要不要合并?看需求,合并就先 toLowerCase()。 3)超长字符串建议用 StringBuilder(我已经用啦),别 + 叠加。 4)如果字符串特别大,Map<Character,Integer> 会顶着内存,你可以考虑 Int2IntOpenHashMap 这类高效实现(面试就别装了,标准库够用)。

行,差不多了,我去泡杯茶…哦对有人问“稳定性”——按我这个写法同频是按字符排序的,不稳定没事儿;你非要稳定,那就堆比较器里再带上一个“首次出现的序号”,就稳了。算了不啰嗦了,先这样哈。

-END-

我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html

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