【快手春招】 工程类笔试A卷题解
注:CSDN上为本人所发,非转载。
1 身高
据说是单调栈,用暴力也能过,不多说了。
public int[] DistanceToHigher (int[] height) { int[] ans = new int[height.length]; for (int i = 1; i< ans.length; i++) { for (int j = i - 1; j >= 0; --j) { if (height[j]>height[i]) { ans[i] = i - j; break; } } } return ans; }
2 次大值
使用两个变量维护当前最大值和次大值,并在读入下一个数后判断是否在两者中间,如果在的话,就说明只有一个数字比它大,输出它的序号,最后更新最大值和次大值。时间复杂度为,空间复杂度为,应该是最优的方案了。
while (sc.hasNextInt()) { int t = sc.nextInt(); if (t >= b2 && t < b1) { System.out.print(pos + " "); } if (t >= b1) { b2 = b1; b1 = t; } else if (t > b2) { b2 = t; } pos++; }
3 靓号
分别维护当前顺子、逆顺子、豹子的计数,为了满足豹子优先,最终将豹子的计数加上1,算法如下:
int a = -2, b = -2, c = -2; int max = 0; for (int i = 4; i < 11; ++ i) { //顺子 if (phone[i] == phone[i-1] + 1) { a += 2; } else { max = Math.max(max, a); a = -2; } //逆顺子 if (phone[i] == phone[i-1] - 1) { b += 2; } else { max = Math.max(max, b); b = -2; } //豹子 if (phone[i] == phone[i-1]) { c += 2; } else { max = Math.max(max, c > 0 ? c + 1 : 0); c = -2; } } max = Math.max(max, Math.max(a, Math.max(b, c > 0 ? c + 1 : 0)));
感觉有点小麻烦,不过可以做到一遍检测的的靓号计算时间复杂度。
确定靓号以后直接创建带有phone
、max
和order
字段的对象放入优先队列(堆),Java在创建优先队列的时候可以传入Comparator
对象作为比较器,可以直接使用lambda传入(o1, o2) -> o1.max == o2.max ? o1.order - o2.order : o2.max - o1.max
,再遍历优先队列输出o.phone
即可。当然,放入List
再快排效果也是一样的,这样使得最终的时间复杂度为,为靓号数量。
4 芯片
我的思路是用二维RMQ(其实也是动态规划)来解决二维区间最小值的查询,用区间DP来解决二维区间求和的问题,这样可以使得二维区间最小值和求和的查询的时间复杂度都为。但是这样做的代价是空间复杂度不低,不知道各位大佬有没有更好的想法。
二维RMQ:https://cloud.tencent.com/developer/article/1093749
第四题太难写了,我没能写完,不知道做出三题多一点能不能过……
#快手##笔试题目#