剑指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 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 getArrayList(int[] numArray,int k)
	{
		ArrayList list = new ArrayList<>(k);
		for(int i = 0;i < k;i++)
		{
			list.add(numArray[i]);		
		}
		return list;
	}
	
	/**
	 * 打印ArrayList中的元素
	 * @param list
	 */
	public void printList(ArrayList 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 list = test.getLeastNumbers(numArray, 1);
		test.printList(list);
	}
}


你可能感兴趣的:(剑指offer(练习))