【快手春招】 工程类笔试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
第四题太难写了,我没能写完,不知道做出三题多一点能不能过……
#快手##笔试题目#
