215. Kth Largest Element in an Array找出数组中第k大的值

堆排序做的,没有全部排序,找到第k个就结束

public int findKthLargest(int[] nums, int k) {
int num = 0;
if (nums.length <= 1)
return nums[0];
int heapSize = nums.length;
//1.构建最大堆
int half = (heapSize-2)/2;
for (int i = half;i >= 0;i--)
{
adjust(nums,heapSize,i);
}
while (heapSize > 1)
{
//2.取出最大值
swap(0,heapSize-1,nums);
heapSize--;
num++;
if(num == k)
break;
//3.调整堆
adjust(nums,heapSize,0);
}
return nums[nums.length-k];
} public void adjust(int[] nums,int heapSize,int index)
{
int left = index*2+1;
int right = index*2+2;
int biggest = index;
if (left < heapSize && nums[left] > nums[biggest])
biggest = left;
//注意这里都是和nums[biggest]比较,别写成index,因为要找出最大的值
if (right < heapSize && nums[right] > nums[biggest])
biggest = right;
if (biggest != index)
{
swap(index,biggest,nums);
adjust(nums,heapSize,biggest);
}
}
public void swap(int a,int b,int[] nums)
{
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}

堆排序的算法时间复杂度是:O(n*log k )

下边快排的改进做法,O(n)

利用快速排序的思想,从数组S中随机找出一个元素X,把数组分为两部分Sa和Sb。Sa中的元素大于等于X,Sb中元素小于X。这时有两种情况:

           1. Sa中元素的个数小于k,则Sb中的第k-|Sa|个元素即为第k大数;
           2. Sa中元素的个数大于等于k,则返回Sa中的第k大数。时间复杂度近似为O(n)
public void findk(int[] nums,int sta,int end,int k)
{
if (sta>end) return;
Random random = new Random();
int p = random.nextInt(end-sta)+sta;
swap(nums,p,sta);
int l = sta;
int r = end;
while (l<r)
{
while (l<r&&nums[r]>=nums[sta])
r--;
while (l<r&&nums[l]<=nums[sta])
l++;
swap(nums,l,r); }
swap(nums,l,sta);
//记录右边数组(包括排序好的数)的大小
int size = end-l+1;
if (size == k) System.out.println(nums[l]);
else if (size<k) findk(nums,sta,l-1,k-size);
else findk(nums,l,end,k);
}
public void swap(int[] nums,int i ,int j)
{
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
上一篇:LeetCode 448. Find All Numbers Disappeared in an Array (在数组中找到没有出现的数字)


下一篇:442. Find All Duplicates in an Array找出数组中所有重复了两次的元素