• 最小的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;
        	
        }
    
  • 相关阅读:
    精准测试
    git 管理
    git
    代码覆盖率测试
    vue 前端视频
    jenkins
    go学习资料
    4-4 求自定类型元素的平均
    4-3 简单求和
    4-2 多项式求值
  • 原文地址:https://www.cnblogs.com/lishanlei/p/10707697.html
Copyright © 2020-2023  润新知