实现思路:
实现思路类似于上一题的求解数组中出现次数超过一半的数字,这道题同样也并没有要求我们将最小的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);
}
}