1. 程式人生 > >找出陣列中最小的 K 個數

找出陣列中最小的 K 個數

給定一個長度為 n 的陣列,要求輸出陣列中最小的 K 個數(k<n)。

思路:

最簡單的思路是將陣列進行排序,由小到大排序,則陣列最前面的 K 個既我們要求的。

但是這樣的時間複雜度為 nlongn,在排序上是最優了,但是在這道題不是。

我們可以利用 快速排序的原理,Partition 函式。將比初始數字 temp 小的數放在左邊,比 temp 放在右邊。

如果 temp 剛好是第 k 個數字,那麼,temp 前面(包括temp)就是所求。

package com.hunter.Offer_Example;

import java.util.Scanner;

/**
 * 給定一個數組,找出陣列中最小 K 個數字
 * 例如給定陣列 1 20 11 12 2 9 10 6 8 18
 *最小的3個數字為: 1  2  6
 * @author luzi
 *
 */
public class findTheKMinNum {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Scanner scan = new Scanner(System.in);
		while(scan.hasNext()){
			int k = scan.nextInt();
			int n = scan.nextInt();
			int[] arr = new int[n];
			for(int i = 0; i < n; i++){
				arr[i] = scan.nextInt();
			}
			int index = Partition(arr,n,0,n-1);
			while(index != k-1){
				if(index > k - 1){
					index = Partition(arr,n,0,index - 1);
				}
				else
					index = Partition(arr,n,index + 1,n-1);
			}
			for(int i =0; i < k; i++)
				System.out.println(arr[i]);
		}
	}

	public static int Partition(int[] arr,int n,int start,int end){
		int temp = arr[start];
		while(start < end){
			
			while(start < end && arr[end] >= temp)
				end--;
			if(start < end)
				arr[start++] = arr[end];
			while(start < end && arr[start] < temp)
				start++;
			if(start < end)
				arr[end--] = arr[start];
		}
		arr[start] = temp;
		return start;
	}
}


實際執行: