小根堆和大根堆
完全二叉树
完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。
满二叉树
除了叶子节点外,每个节点的两个子节点都全的二叉树。
小根堆
首先小根堆是一个完全二叉树,并且任何子树的最小值是它的根节点。
大根堆
同理,大根堆也是一个完全二叉树,并且任何子树的最大值是它的根节点。
应用
问题
京东笔试题
第一行一个数字n,表示序列nums的长度,之后一行一个长度为n序列,每个数字用空格分割,求所有子序列的中位数之和。
我们可以用一个大根堆和一个小根堆动态的寻找中位数,每次寻找中位数的复杂度为O(longn)。
用大小根堆解题
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n=Integer.parseInt(in.nextLine());
String[] sarr=in.nextLine().split(" ");
int[] arr=new int[sarr.length];
for(int i=0;i<arr.length;i++){
arr[i]=Integer.parseInt(sarr[i]);
}
long re=0;
for(int i=0;i<arr.length;i++){
PriorityQueue<Integer> queue_min =
new PriorityQueue<Integer>((o1,o2) -> o1 - o2);
PriorityQueue<Integer> queue_max =
new PriorityQueue<Integer>((o1,o2) -> o2 - o1);
int flag=arr[i];
re+=flag;
for(int j=i+1;j<arr.length;j++){
//System.out.println(re);
if(flag>arr[j]){
if(queue_max.size()<=queue_min.size()){
queue_max.add(flag);
flag=arr[j];
re+=flag;
}
else if(queue_max.size()>queue_min.size()){
queue_min.add(arr[j]);
re+=flag;
}
}
else{
if(queue_max.size()>=queue_min.size()){
queue_min.add(arr[j]);
re+=flag;
}
else if(queue_max.size()<queue_min.size()){
queue_max.add(flag);
flag=arr[j];
re+=flag;
}
}
}
//System.out.println(re);
//System.out.println("================");
}
System.out.println(re);
}
}
本文介绍如何利用小根堆和大根堆解决京东笔试题中的中位数求和问题。通过动态维护两个堆,可以在O(log n)的时间复杂度内找到任意子序列的中位数,并计算所有子序列的中位数之和。
170万+

被折叠的 条评论
为什么被折叠?



