Sword finger Offer: the minimum number of k

Keywords: less

Title Description

Enter n integers to find the minimum number of K. For example, if you enter 8 numbers of 4,5,1,6,2,7,3,8, the minimum 4 numbers are 1,2,3,4

Use quick sort

Using quicksort, if equal to the area containing the K position, returns the number of 0-k positions:

public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> list = new ArrayList<>();
        if(input==null || input.length==0 || k>input.length) return list;
        int L=0;
        int R=input.length-1;
        while(L<=R){
            int[] res=partition(input,L,R);//Get subscript equal to region
            if(k-1>=res[0] && k-1<=res[1]){ //If k-1 (subscript representing the smallest number k) is located in the equal area, simply add the number of 0-k positions
                for(int i=0;i<k;i++){
                        list.add(input[i]);
                }
                return list;
            }else if(k-1<res[0]){
                    R=res[0]-1;
            }else if(k-1>res[1]){
                    L=res[1]+1;
                }
        }
          return list;
  }
    public int[] partition(int[] arr,int L,int R){
        int less=L-1;
        int big=R+1;
        int temp=arr[L];
        while(L<big){
            if(arr[L]<temp){
                swap(arr,++less,L++);
            }else if(arr[L]>temp){
                swap(arr,L,--big);
            }else{
                L++;
            }
        }
        return new int[]{less+1,big-1};
    }
    public void swap(int[] arr,int i,int j){
        int temp=arr[i];
        arr[i]=arr[j];
        arr[j]=temp;
    }
}

Bubble like sorting

Similar to bubble sorting, each time you put the minimum number to the last place, you can return it by putting k pieces. You do not need to sort all:

public class Solution {
   public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
       ArrayList<Integer> list = new  ArrayList<>();
       if(input==null || input.length==0 || k>input.length ) return list;
       for(int i=0;i<k;i++){
           for(int j=1;j<input.length-i;j++){
               if(input[j-1]<input[j]){
                   swap(input,j-1,j);
               }
           }
           list.add(input[input.length-1-i]);
       }
       return list;
   }
   public void swap(int[] arr,int i,int j){
       int temp = arr[i];
       arr[i]=arr[j];
       arr[j]=temp;
   }
}

Building a big root pile

To create a large heap, if the number of positions i is smaller than the heap top, remove the heap top and add this number:

public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> list = new ArrayList<>();
        if(input==null || input.length==0 || k>input.length || k==0) return list;
        int[] heap = new int[k];
        for(int i=0;i!=k;i++){
            heapInsert(heap,input[i],i);//0-k to build a large root pile
        }
        for(int i=k;i!=input.length;i++){//Start from k and compare one by one. If it is smaller than the top of the big root heap, replace the top of the heap and adjust it to the big root heap
            if(heap[0]>input[i]){
                heap[0]=input[i]; //If it is smaller than the top of the big pile, replace the top
                heapSort(heap,0,k);//Readjust to a large pile
            }
        }
        for(int i=0;i!=heap.length;i++){
            list.add(heap[i]);
        }
        return list;
         
    }
    public void heapInsert(int[] arr,int val,int i){ //Building a big root pile
        arr[i] = val;
        while(i!=0){
            int parent = (i-1)/2;
            if(arr[parent] < arr[i]){
                int temp=arr[parent];
                arr[parent] = arr[i];
                arr[i]=temp;
                i=parent;
            }else{
                break;
            }
        }
    }  
    public void heapSort(int[] arr,int index,int size){//The process of adjusting the big root heap, compared with the left and right subtrees
        int left = 2*index+1;
        int right= 2*index+2;
        int largest = index;
        while(left<size){
            if(arr[index]<arr[left]){
                largest = left;
            }
            if(right<size && arr[right]>arr[largest]){
                largest = right;
            }
            if(largest!=index){
                int temp=arr[index];
                arr[index] = arr[largest];
                arr[largest]=temp;
            }else{
                break;
            }
            index=largest;
            left = 2*index+1;
            right=2*index+2;
        }
    }
}

Use priority queue

The priority queue is directly used to realize the large root heap structure:

public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> list = new ArrayList<>();
        if(input==null || input.length==0 || k>input.length || k==0) return list;
        PriorityQueue<Integer> queue = new PriorityQueue<>(k,new Comparator<Integer>(){
            public int compare(Integer a,Integer b){
                return b-a;
            }
        });
        for(int i=0;i<k;i++){
            queue.offer(input[i]);
        }
        for(int i=k;i<input.length;i++){
            if(queue.peek()>input[i]){
                queue.poll();
                queue.offer(input[i]);
            }
        }
        for(Integer i:queue ){
            list.add(i);
        }
        return list;
    }
}

Posted by deras on Sat, 23 Nov 2019 07:17:42 -0800