杀人诛心!推荐的面试候选人,连一道最基础的“三数求和(3 Sum)”题都无法完成。因此,我们决定也为你重新安排一次技术面试~
真有点杀人诛心那味儿了。
网友说自己推荐了个面试候选人,结果人家技术面一上来,连“三数求和”这种基础算法题都没写出来。正常流程吧,也就候选人挂了,推荐人尴尬一下,事儿差不多过去了。
结果公司这边更狠,直接反手一句:我们现在开始怀疑你的判断能力,也怀疑你当初到底怎么评估这个人的。所以,别光他面了,你也重新来一轮技术面试吧。
推荐失败不可怕,可怕的是领导突然发现,问题可能不在候选人身上,而在“你怎么敢推荐他”。本来以为自己是帮朋友递个简历,最后变成自己也被拉进考场。HR看完都得沉默,程序员看完背后一凉。
以后内推真别随便拍胸脯,尤其技术岗。你以为是送人情,别人可能当场给你开个回旋镖。
这个题第一眼别急着写排序。
“回答率最高”这几个字,坑就埋在分母里。不是看哪个问题回答次数最多,也不是看 answerId 有没有值,而是:
回答率 = answer 次数 / show 次数
线上这种日志表一般长这样:
uid action question_id
1 show 101
1 answer 101
2 show 101
3 show 102
3 answer 102
4 show 102
4 answer 102
问题 101 被展示 2 次,回答 1 次,回答率 1/2。
问题 102 被展示 2 次,回答 2 次,回答率 2/2。
所以答案是 102。
这里我一般不先算小数。小数有精度问题,虽然这题数据量不一定大,但没必要给自己找事。比较 a/b 和 c/d,直接比较 a*d 和 c*b 就行。
Java 写法可以这样:
import java.util.*;
classSolution{
staticclassLog{
int questionId;
String action;
Log(int questionId, String action) {
this.questionId = questionId;
this.action = action;
}
}
publicintgetHighestAnswerRateQuestion(List<Log> logs){
Map<Integer, int[]> stat = new HashMap<>();
for (Log log : logs) {
int[] bucket = stat.computeIfAbsent(log.questionId, k -> newint[2]);
if ("show".equals(log.action)) {
bucket[0]++;
} elseif ("answer".equals(log.action)) {
bucket[1]++;
}
}
int bestQuestion = -1;
int bestAnswer = -1;
int bestShow = 1;
for (Map.Entry<Integer, int[]> entry : stat.entrySet()) {
int questionId = entry.getKey();
int show = entry.getValue()[0];
int answer = entry.getValue()[1];
if (show == 0) {
continue;
}
if (bestQuestion == -1
|| answer * bestShow > bestAnswer * show
|| answer * bestShow == bestAnswer * show && questionId < bestQuestion) {
bestQuestion = questionId;
bestAnswer = answer;
bestShow = show;
}
}
return bestQuestion;
}
}
这段代码里,int[0] 放展示次数,int[1] 放回答次数。别看数组不如对象优雅,算法题里够用了,少写一堆没意义的类。
真正要注意的是这行:
answer * bestShow > bestAnswer * show
它避开了除法。
如果写成:
answer / show
那就直接翻车了,Java 里两个整数相除还是整数。1 / 2 结果是 0,不是 0.5。
如果强转成 double 当然也能做:
double rate = answer * 1.0 / show;
但我不太爱这么写。比较比例,本来就可以用交叉相乘,干净。
还有一个边界要挡一下:有些问题可能只有 answer 日志,没有 show 日志。正常业务不该这样,但日志题别太相信数据干净。所以 show == 0 直接跳过。
最后如果两个问题回答率一样,我这里返回 questionId 更小的那个。面试时这个规则最好问一句;没给规则,就自己写稳定一点,别让结果飘。