剑指offer-----面试题30(最小的k个数)

实现思路:

        实现思路类似于上一题的求解数组中出现次数超过一半的数字,这道题同样也并没有要求我们将最小的k个数按顺序输出来,因此我们可以借助于快速排序寻找主元的位置的方法来实现,因为主元位置的左边都是小于主元的,主元位置的右边都是大于主元的,我们只需要不断的调用查找主元位置的方法直到主元位于k位置就可以了,当然没进行一次partition方法,主元本身也是在变化的,这时候主元位置左边的数组元素就是最小的k个数了;

实现代码:

import java.util.ArrayList;

/**
 * 面试题30
 * 最小k个数
 * @author 扇扇来驰
 *
 */
public class GetLeastKNumbers {
	/**
	 * 获取数组中最小的K个数
	 * @param numArray
	 * @param k
	 * @return
	 */
	public ArrayList<Integer> getLeastNumbers(int[] numArray,int k)
	{
		if(numArray == null)
			return null;
		if(k > numArray.length)
			return new ArrayList<>();
		if(k == numArray.length)
			return getArrayList(numArray, k);
		int position = partition(numArray, 0, numArray.length-1);
		while(position != k)
		{
			if(position < k)
				position = partition(numArray, position+1, numArray.length-1);
			else if(position > k)
				position = partition(numArray, 0, position-1);
		}
		return getArrayList(numArray, k);
	}
	/**
	 * 快速排序中获得主元位置的方法
	 * @param numArray
	 * @param startIndex
	 * @param endIndex
	 * @return
	 */
	public int partition(int[] numArray,int startIndex,int endIndex)
	{
		int position = startIndex;
		int privot = numArray[position];
		while(startIndex < endIndex)
		{
			while(startIndex < endIndex && numArray[endIndex] >= privot)
				endIndex--;
			if(startIndex < endIndex && numArray[endIndex] < privot)
			{
				change(numArray, position, endIndex);
				position = endIndex;
			}
			while(startIndex < endIndex && numArray[startIndex] <= privot)
				startIndex++;
			if(startIndex < endIndex && numArray[startIndex] > privot)
			{
				change(numArray, position, startIndex);
				position = startIndex;
			}
		}
		return position;
	}
	
	/**
	 * 交换数组中两个位置上的元素
	 * @param numArray
	 * @param firstIndex
	 * @param secondIndex
	 */
	public void change(int[] numArray,int firstIndex,int secondIndex)
	{
		int temp = numArray[firstIndex];
		numArray[firstIndex] = numArray[secondIndex];
		numArray[secondIndex] = temp;
	}
	
	/**
	 * 将数组中的前k个数返回成ArrayList
	 * @param numArray
	 * @param k
	 * @return
	 */
	public ArrayList<Integer> getArrayList(int[] numArray,int k)
	{
		ArrayList<Integer> list = new ArrayList<>(k);
		for(int i = 0;i < k;i++)
		{
			list.add(numArray[i]);		
		}
		return list;
	}
	
	/**
	 * 打印ArrayList中的元素
	 * @param list
	 */
	public void printList(ArrayList<Integer> list)
	{
		for(int i = 0;i < list.size();i++)
			System.out.print(list.get(i)+"  ");
	}
	public static void main(String[] args) {
		int[] numArray = {4,5,1,6,2,7,3,8};
		GetLeastKNumbers test = new GetLeastKNumbers();
		ArrayList<Integer> list = test.getLeastNumbers(numArray, 1);
		test.printList(list);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值