最小的K个数

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

      import java.util.*;
      import java.util.stream.Collectors;
    
      /**
       * 输入n个整数,找出其中最小的K个数。
       * 例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
       * Created by etf on 2018/4/9.
       */
      public class Solution29 {
    
      	/**
      	 * 直接排序
      	 */
      	public ArrayList<Integer> GetLeastNumbers_Solution1(int [] input, int k) {
      		if (k < 0 || k > input.length) {
      			return new ArrayList<>();
      		}
      		Arrays.sort(input);
      		List<Integer> list = Arrays.stream(input)
      				.boxed().collect(Collectors.toList());
      		return new ArrayList<>(list.subList(0, k));
      	}
    
      	/**
      	 * 剪枝法
      	 */
      	public ArrayList<Integer> GetLeastNumbers_Solution2(int [] input, int k) {
    
      		int len = input.length;
    
      		if (k <= 0 || k > len) {
      			return new ArrayList<>();
      		}
      		int start = 0;
      		int end = len - 1;
      		int index = partition(input, start, end);
      		while (start < end && index != k - 1) {
      			if (index > k - 1) {
      				end = index - 1;
      				index = partition(input, start, end);
      			} else if (index < k - 1) {
      				start = index + 1;
      				index = partition(input, start, end);
      			} else {
      				break;
      			}
      		}
      		return new ArrayList<>(Arrays.stream(input)
      				.boxed().collect(Collectors.toList()).subList(0, k));
      	}
    
      	/**
      	 * 获取 start 位置元素在数组排序后的位置
      	 */
      	private int partition(int[] input, int start, int end) {
      		int low = start;
      		int high = end;
      		int temp = input[low];
      		while (low < high) {
      			while (low < high && temp <= input[high]) {
      				high --;
      			}
      			input[low] = input[high];
      			while (low < high && temp >= input[low]) {
      				low ++;
      			}
      			input[high] = input[low];
      		}
      		input[low] = temp;
      		return low;
      	}
    
    
      	public ArrayList<Integer> GetLeastNumbers_Solution3(int [] input, int k) {
      		int len = input.length;
    
      		if (k <= 0 || k > len) {
      			return new ArrayList<>();
      		}
    
      		//构建大顶堆
      		for (int i = k / 2 - 1; i >= 0 ; i--) {
      			adjustMaxHeap(input, i, k - 1);
      		}
      		for (int j = k; j < len; j++) {
      			if (input[j] < input[0]) {
      				int temp = input[j];
      				input[j] = input[0];
      				input[0] = temp;
      				adjustMaxHeap(input, 0, k - 1);
      			}
      		}
    
      		return new ArrayList<>(Arrays.stream(input)
      				.boxed().collect(Collectors.toList()).subList(0, k));
      	}
    
      	//调整堆
      	private void adjustMaxHeap(int[] input, int start, int end) {
      		int temp = input[start];
      		for (int i = start * 2 + 1; i <= end; i = i * 2 + 1) {
      			if (i < end && input[i] < input[i+1]) { //取节点较大的子节点的下标
      				i++;
      			}
      			if (temp >= input[i]) {  //根节点 >= 孩子中关键字较大者,调整结束
      				break;
      			} else {    //根节点 < 孩子中关键字较大者
      				input[start] = input[i];
      				start = i;  //继续向下调整
      			}
      		}
      		input[start] = temp;
      	}
      }
    

转载于:https://my.oschina.net/u/3839325/blog/2051067

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值