解法1:优先级队列
优先级队列:小根堆
PriorityQueue<Integer> queue=new PriorityQueue<>(new Comparator<Integer>(){
public int compare(Integer a,Integer b){
return a.compareTo(b);
}
});
// PriorityQueue<Integer> queue = new PriorityQueue();最小k个数:大根堆
PriorityQueue<Integer> maxHeap=new PriorityQueue<Integer>
(k,new Comparator<Integer>(){
@Override
public int compare(Integer o1,Integer o2){
return o2.compareTo(o1);
}
});
PriorityQueue<Integer> maxHeap=new PriorityQueue<Integer>(k,(a,b)->b.compareTo(a)); 思路:最大优先队列,无论入队顺序,当前最大的元素优先出队。
用最大堆来实现最大优先队列,每一次入队操作就是堆的插入操作,每一次出队操作就是删除堆顶节点。堆节点的上浮和下沉的时间复杂度为logN,所以优先队列入队和出队的时间复杂度也为logN
import java.util.ArrayList;
import java.util.PriorityQueue;
import java.util.Comparator;
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
if(k <=0 || k > input.length || input.length==0){
return new ArrayList<Integer>(0);
}
PriorityQueue<Integer> maxHeap=new PriorityQueue<Integer>(k,new Comparator<Integer>(){
@Override
public int compare(Integer o1,Integer o2){
return o2.compareTo(o1);
}
});
for(int i=0;i<k;i++){
maxHeap.add(input[i]);
}
for(int i=k;i<input.length;i++){
if(maxHeap.peek()>input[i]){
maxHeap.poll();
maxHeap.add(input[i]);
}
}
return new ArrayList<Integer>(maxHeap);
}
}解法2:冒泡排序的改进:冒K次
冒泡排序的思想,只不过最外层循环K次就可以了;
也就是说不用全部排序;只挑出符合提议的K个就可以;
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
ArrayList<Integer> al = new ArrayList<Integer>();
if (k > input.length) {
return al;
}
for (int i = 0; i < k; i++) {
for (int j = 0; j < input.length - i - 1; j++) {
if (input[j] < input[j + 1]) {
int temp = input[j];
input[j] = input[j + 1];
input[j + 1] = temp;
}
}
al.add(input[input.length - i - 1]);
}
return al;
}解法3:堆排序 / 快速排序
//快速排序
import java.util.*;
public class Finder {
public int findKth(int[] a, int n, int K) {
// write code here
quicksort(a,0,n-1);
return a[n-K];
}
public void quicksort(int[] a,int start,int end){
if(start<end){
int part=partition(a,start,end);
quicksort(a,start,part-1);
quicksort(a,part+1,end);
}
}
public int partition(int[]a,int l,int r){
int pivot=l;
int index=l+1;
for(int i=l+1;i<=r;i++){
if(a[i]<a[pivot]){
swap(a,i,index);
index++;
}
}
swap(a,pivot,index-1);
return index-1;
}
public void swap(int[] a,int i,int j){
int tmp=a[i];
a[i]=a[j];
a[j]=tmp;
}
}//堆排序
public findKth(int[] a, int n, int K) {
heapSort(a);
return a[n-K];
}
public static void heapSort(int[] arr){
if(arr == null || arr.length<2){
return;
}
for(int i=0;i<arr.length;i++){
heapInsert(arr,i); //构造完全二叉树
}
int size = arr.length;
swap(arr,0,--size);
while(size>0){
heapify(arr,0,size);// 最后一个数与根交换
swap(arr,0,--size);
}
}
//判断该结点与父结点的大小,大结点一直往,建立大根堆
public static void heapInsert(int[] arr,int index){
while(arr[index]>arr[(index-1)/2]){
swap(arr,index,(index-1)/2);
index=(index-1)/2;
}
}
//一个值变小往下沉的过程
public static void heapify(int[] arr,int index,int size){
int left=index*2+1;
while(left<size){
int largest = left + 1 < size && arr[left+1] > arr[left] ? left+1 : left;
largest = arr[largest] > arr[index] ? largest :index;
if(largest==index){
break;
}
swap(arr,largest,index);
index=largest;
left=index*2 +1;
}
}
//交换函数
public static void swap(int[] arr, int i, int j){
int tmp;
tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
京公网安备 11010502036488号