//题目描述:
//输入n个整数,找出其中最小的K的数.例如,输入4,5,1,6,2,7,3,8折8个数,
//则最小的4个数字是1,2,3,4.
public class Solution
{
//解题思路:
//要找出最小的K的数,首先考虑到排序,再选出前K个数.但是还不够快.这样的时间复杂度是O(nlogn).
//借用快排的思想.只要先找出找出第K小的元素,再用快排,这样K左边就是比K 小的元素.时间复杂度为O(1).
//但是要找出第K小的元素也是一个问题.所以直接循环判断整个数组,找出快排一次后左边的元素个数是K个,就找到了最小的K个元素.
//这样的时间复杂度是O(n) + O(1).
// 但是只有当允许修改数组元素时才可以使用
public ArrayList<Integer> getKthNumber(int[] nums, int k)
{
ArrayList<Integer> res = new ArrayList<>();
//初始判断
if (nums.length == 0 || nums == null || k < 0 || k > nums.length)
{
return null;
}
int l = 0, h = nums.length - 1;
//开始循环判断,有点类似二分法.
while (l < h)
{
int j = quickSelect(nums, l, h);
if (j > k)
{
h = j - 1;
}
else if (j < k)
{
l = j + 1;
}
else
{
break;
}
}
//从index为0的到K-1的是最小一K个数.
for (int i = 0; i < k; i++)
{
res.add(nums[i]);
}
return res;
}
//快排
private int quickSelect(int[] nums, int l, int h)
{
int p = nums[l];
int i = l, j = h + 1;
while (i < j)
{
while (i < j && nums[++i] < p) ;
while (i < j && nums[--j] > p) ;
swap(nums, i, j);
}
swap(nums, l, j);
return j;
}
private void swap(int[] nums, int i, int j)
{
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
}
《剑指offer》NO40 最小的K个数 详解 <Java实现>
最新推荐文章于 2021-04-06 21:00:09 发布