1. 程式人生 > >劍指offer第六天

劍指offer第六天

函數 style clas java nbsp 定制 err solution ride

29.最小的K個數

輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4。

解法一:

Partition思想

允許改變原始數組的情況,時間復雜度O(n),不適合海量數據

import java.util.ArrayList;
public class Solution {
    /*解法一:允許改變原始數組的情況,時間復雜度O(n),不適合海量數據*/
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList
<Integer> result = new ArrayList<>(); //註意如果輸入不合法,這裏返回的是一個空集合,不是Null,與return null不同 if(input == null || k<0 || k>input.length) return result; int start = 0; int end = input.length-1; int smallNums = partition(input,start,end);
while(smallNums != k-1){ if(smallNums > k-1) smallNums = partition(input,start,smallNums-1); else if(smallNums < k-1) smallNums = partition(input,smallNums+1,end); } for(int i =0;i<k;i++){ result.add(input[i]); }
return result; } //快排方法功能函數,在指定範圍內隨機選取一個數字,將數組中大與等於的放置其又,小於的放置其左; //返回值是在變換位置後,該元素的索引值 public static int partition(int[] array,int start,int end){ //邊界檢測 if(array == null || array.length == 0 || start < 0 || end >= array.length || start > end) return -1; //在[start,end]範圍內,隨機選取一個數作為index int randomIdx = (int)(start + Math.random()*(end-start)); //int length = array.length; int smallNums = start-1; swap(array,randomIdx,end); for(int i=start;i<end;i++){ if(array[i] < array[end]){ smallNums++; if(smallNums < i){ swap(array,smallNums,i); } } } smallNums++; swap(array,smallNums,end); return smallNums; } //交換元素 public static void swap(int[] array,int i,int j){ int temp = array[i]; array[i] = array[j]; array[j] = temp; } }

解法二:

使用最大堆思想,通過優先隊列的Conparator定制排序,實現指定大小的最大堆。

import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue;
public class Solution {
    //解法二:不改變原始數組,使用優先隊列,時間復雜度O(nlogk),適合海量數據
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> result = new ArrayList<>();
        if(input == null || k > input.length || k<=0) return result;
        PriorityQueue<Integer> maxQueue = new PriorityQueue(k,new Comparator<Integer>(){
            @Override
            public int compare(Integer o1,Integer o2){
                return o2.compareTo(o1);//將先前Integer中的自然排序(從小到大)反過來,實現從大到小;
            }
        });
        for(int i =0;i<input.length;i++){
            if(maxQueue.size() != k ){
                maxQueue.offer(input[i]);
            }else if(maxQueue.peek() > input[i]){
                Integer temp = maxQueue.poll();//必須先去除隊列頭部的數據,以保證隊列長度
                temp = null;
                maxQueue.offer(input[i]);
            }
        }
        for(Integer i : maxQueue){
            result.add(i);
        }
        return result;
    }
}

劍指offer第六天