剑指offer:(30)时间效率 :最小的K个数

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

package cn.com.jianzhioffer;


import java.util.ArrayList;

public class Solution30 {
//	public ArrayList<Integer> GetLeastNumbers_Solution(int[] input,int k){
//		ArrayList<Integer> list = new ArrayList<Integer>();
//		if(input==null||k>input.length)  return list;
//		for(int i = 0;i<k;i++){
//			for(int j=i;j<input.length;j++){
//				if(input[i]>input[j]){
//					int t = input[i];
//					input[i] = input[j];
//					input[j] = t;
//				}
//			}
//			list.add(input[i]);
//		}
//		return list;
//	}
	
	/*
	 * 方法一:o(n),此时要求可以修改数组
	 * 基于Partition函数来解决
	 * 如果基于数组的第k个数字来调整,使比第k个数字小的所有数字都位于数组的左边,
	 * 比第k个数字大的所有数字都位于数组的右边
	 * 这样之后,位于数组中左边的k个数字就是最小的k个数字(这k个数字不一定有序)
	 */
	public ArrayList<Integer>  GetLeastNumbers(int[] input,int k){
		ArrayList<Integer> list = new ArrayList<Integer>();
		int length = input.length;
		if(input==null||length<=0||k>length||k<=0) return list;
		int start = 0;
		int end = length-1;
		int index = Partition(input, start, end);
		while(index!=(k-1)){
			if(index>k-1){
				end = index-1;
				index = Partition(input, start, end);
			}else{
				start = index+1;
				index = Partition(input, start, end);
			}
		}
		for(int i = 0;i<k;i++){
			list.add(input[i]);
		}
		return list;
		
	}
	//一次快排
	public int Partition(int[] input,int start,int end){
		int i = start;
		int j = end;
		
		int key = input[i];
		while(i<j){
			//按j--方向遍历目标数组,直到比key小的值为止
			while(i<j&&key<=input[j]){
				j--;
			}
			if(i<j){
				//input[i]已经保存在key中,可以将后面的数填入
				input[i] = input[j];
				i++;
			}
			//按i++方向遍历数组,直至比key大的值为止
			while(i<j&&input[i]<=key){
				i++;
			}
			if(i<j){
				//input[j]已经保存在input[i],可将前面的值填入
				input[j] = input[i];
				j--;
			}			
		}
		//此时i==j
		input[i] = key;
		return i;
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值