多次操作一个数组arr,返回数组中剩下的最后一个数的最大值
提示:阿里20220407笔试手撕算法第2题
文章目录
题目
输入2行,第一行n,代表n个数字,
第二行一个数组,就是你要输入的n个数字arr[i],现在对数组的任意其中2个数进行操作:
1)如果有俩相同的数,将其求和,然后sum放入arr;
2)如果俩数不相同,则取两者最大值max,放入arr;
不断循环操作,直到arr中只剩下1个数,返回这个数可能的最大值是多少?
一、审题
比如:
n = 3,代表3个数的数组长度,分别是:
2 4 4
第一次操作,肯定拿4+4=8,然后放回数组,2 8
第二次操作,既然不同,则选最大值8返回结果。
二、解题
非常容易理解的一个题目,当时笔试我瞬间就想到用小根堆解决
解题大流程:
你既然要最大值,那么肯定有一个排序问题,而且每次操作都从最小的俩数玩,取堆顶的俩数,
如果相同就加,然后放回小根堆,
如果不相同,则选最最大值放入小根堆,
当小根堆的size为1,返回堆顶元素。
这就是我练习了很久的数据结构与算法之后,培养出来的解题敏感度,非常非常敏感,而且迅速把代码写出来了,AC。
代码:
public static class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
int n = in.nextInt();
int[] arr = new int[n];
PriorityQueue<Integer> heap = new PriorityQueue<>();//默认小根堆?
for (int i = 0; i < n; i++) {
arr[i] = in.nextInt();
heap.add(arr[i]);
}
while (heap.size() != 1){
//只有heap1个停下来
int cur = heap.poll();//弹出1个
if (cur == heap.peek()){
//有相同的数
int sum = cur + heap.poll();//弹出
heap.add(sum);//又放回去
}else {
//否则俩就是不相同,那就选最大放入
int max = Math.max(cur, heap.poll());
heap.add(max);//又放回去
}
}
//只有一个那就打印
System.out.println(heap.peek());
}
}
总结
提示:重要知识点:
1)平时多积累,多学习,读练习,培养数据结构与算法的敏感度,能瞬间感知这个题应该用什么数据结构解决;