最小的K个数

题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

方法一
基于随机快排思想,基于数组的第k个数字来调整,则使得比第k个数字小的所有数字都在数组的左边,比k大的数字都在数组的右边。这样调整之后位于数组中左边的k个数字就是最小的k个数字。

	/**
	 * 利用快排思想,时间复杂度O(n)
	 * @param input
	 * @param k
	 * @return
	 */
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
    	ArrayList<Integer> list = new ArrayList<Integer>();
    	if(input == null || input.length == 0 || k > input.length || k <= 0) {
    		return list;
    	}
    	
    	int start = 0;
    	int end = input.length - 1;
    	int index = Partition(input, start, end);
    	
    	while(index != k - 1) {
    		if(index < (k - 1)) {
    			start = index + 1;
    			index = Partition(input, start, end);
    		}
    		else {
    			end = index - 1;
    			index = Partition(input, start, end);
    		}
    	}
    	for (int i = 0; i < k; i++) {
			list.add(input[i]);
		}
    	
    	return list;
    	
    }
    
    public int Partition(int[] elem, int low, int high) {
    	int pivotkey = elem[low];
    	while(low < high) {
    		while((low < high) && elem[high] > pivotkey) {
    			high--;
    		}
    		swap(elem, low, high);
    		
    		while((low < high) && elem[low] <= pivotkey) {
    			low++;
    		}
    		swap(elem, low, high);
     	}
    	return low;
    }
    
    public void swap(int[] elem, int i, int j) {
    	int temp = elem[i];
    	elem[i] = elem[j];
    	elem[j] = temp;
    }

方法二
利用最大堆的思想,创建一个大小为k的最大堆用来存储最小的k个数字。接下来每次从输入的n个整数中读入一个数。如果最大堆中已有的数字小于k个,直接将这个整数存放进去。如果已经满了,应该替换最大堆中最大的数字。而根据最大堆的特性,根节点的值比所有节点都大,所以可以实现O(1)的最大数的查找。不过在插入删除时需要O(logk)的时间来完成。

import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue;

    public ArrayList<Integer> GetLeastNumbers_Solution_2(int [] input, int k) {
    	ArrayList<Integer> list = new ArrayList<Integer>();
    	if(input == null || input.length == 0 || k > input.length || k <= 0) {
    		return list;
    	}
    	//创建一个最大堆
    	PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(11, new Comparator<Integer>() {
    		public int compare(Integer i1, Integer i2) {
    			return i2.compareTo(i1);
    		}
    	});
    	
    	for (int i = 0; i < input.length; i++) {
			if(maxHeap.size() < k) {
				maxHeap.add(input[i]);
			}
			else {
				if(maxHeap.peek() <= input[i]) {
					continue;
				}
				else {
					maxHeap.poll();
					maxHeap.add(input[i]);
				}
			}
		}
    	for (Integer integer : maxHeap) {
			list.add(integer);
		}
    	
    	return list;
    	
    }
posted @ 2019-03-25 22:16  如是说  阅读(273)  评论(0编辑  收藏  举报