Java实现TopK问题的方法
面试中会经常遇到手撕代码的情况,而求TopK的是经常遇到的题目。下面我就用Java来实现。主要通过两种方法实现,快排思想以及堆排序的思想,两者的复杂度为O(NlogK)。
基于快排的TopK实现:
importjava.util.Arrays;
/**
*使用快排实现的TopK问题Title:Description:Company:
*
*@author郑伟
*@date2018年4月10日下午9:28:15
*/
publicclassTopK_PartitionSort{
publicstaticvoidmain(String[]args){
int[]num={2,20,3,7,9,1,17,18,0,4};
partitionSort(num,0,num.length-1,3);
System.out.println(Arrays.toString(num));
}
publicstaticvoidpartitionSort(int[]nums,intlow,inthigh,intK){
if(low=nums[low]){
++low;
}
//找到比pivotkey大的书了,那就交换
temp=nums[low];
nums[low]=nums[high];
nums[high]=temp;
//这时,pivotkey对应于nums[low]
}
returnlow;//返回pivotkey对应的正确位置
}
}
其实整个代码和快排一样,就是多了一个下标位置的判断,if(K-1==pointKey),这是核心,也就是为什么复杂度为NlogK。如果看不懂,可以先去理解快排的实现。
堆排序实现TopK:
/**
*使用堆排序实现的TopK问题Title:Description:Company:
*
*@author郑伟
*@date2018年4月11日上午9:28:15
*/
publicclassTopK_HeapSort{
publicstaticvoidmain(String[]args){
int[]num={2,20,3,7,9,1,17,18,0,4};
heapSort(num,3);
System.out.println(Arrays.toString(num));
}
/**
*堆排序
*
*@paramnum
*/
privatestaticvoidheapSort(int[]num,intK){
for(inti=num.length/2-1;i>=0;i--){
adjustMin(num,i,num.length);//调整0~num.length-1的数据
}
//如果要实现topK,就在这里执行
for(intj=num.length-1;j>=0&&K>0;j--,K--){
//交换最后一个
swap(num,0,j);
//再次调整0~j-1的数据
adjustMin(num,0,j);
}
//使用最大堆,K=3,输出[9,7,3,2,4,1,0,17,18,20],最大的三个值17,18,20
//使用最小堆,K=3,输出[3,4,9,7,20,18,17,2,1,0],最小的三个值2,1,0
}
/**
*交换栈顶和最后一个元素
*
*@paramnum
*@parami
*@paramj
*/
privatestaticvoidswap(int[]num,inti,intj){
inttem=num[i];
num[i]=num[j];
num[j]=tem;
}
/**
*调整为大顶堆
*
*@paramnum
*@paramroot_index
*/
privatestaticvoidadjust(int[]num,introot_index,intlength){
//
introot=num[root_index];
for(intj=root_index*2+1;jnum[k+1])
k=k+1;//K指向最小的子节点
if(num[k]
算法核心思想:与一般的堆排序不同的是,TopK只需要堆尾与堆顶交换K次就好,不需要全部交换一遍。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。