LeetCode Kth Largest Element in an Array

来源:互联网 发布:美国仓库淘宝网 编辑:程序博客网 时间:2024/06/10 00:10

大家好,我是刘天昊,今天给大家带来的是《算法导论》里的一种算法在LeetCode中的体现

同样是c语言给大家实现,废话不多说先看题目

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

For example,
Given [3,2,1,5,6,4] and k = 2, return 5.

Note: 
You may assume k is always valid, 1 ≤ k ≤ array's length.


这道题找的是数组里第k个大的数

好大家肯定觉得不难很简单嘛,先排序,然后再找第k个大的数嘛

bingo,你回答的很棒,完美--那么先来分析下这种情况的时间复杂度吧

快排序(堆排序,或者归并排序更好)但是我们这里用快排序主要是为了跟大家说后面的算法

void QuickSort(int *nums,int left,int right){    int pivot=nums[left];    int i=left;    int j=right;    if(i>j)    {        return ;    }    while(i!=j)    {        while(i<j&&nums[j]>=pivot)        {            j--;        }        while(i<j&&nums[i]<=pivot)        {            i++;        }        if(i<j)        {            nums[j]=nums[i]^nums[j];            nums[i]=nums[i]^nums[j];            nums[j]=nums[i]^nums[j];        }    }    nums[left]=nums[i];    nums[i]=pivot;    QuickSort(nums,left,i-1);    QuickSort(nums,i+1,right);}int findKthLargest(int* nums, int numsSize, int k){    QuickSort(nums,0,numsSize-1);    int count=1;    for(int i=numsSize-1;i>=0;i--)    {        if(count==k)        {            return nums[i];        }        count++;    }    return 0;}
这里是给大家现写的,因为你拿到这题不应该去这么处理我们有线性的处理方案,不过这种大家都可以理解

这个跑完的速度是49ms记住这个数后面我们会比较

这里没有用随机快排序因为在leetcode上随机快排序我没跑出来-。-!

所以后面的算法也不是Randomlized Select K不过never mind

接下来现说说看怎么去找第K个小的元素(numSize-1-k的大元素,没理解面壁去)

我很少写伪代码但是这次写个,愿意看的看,不愿意看可以直接代码

SelectK(A,left,right,I)(A是数组,I就是k)

if left==right

return A[left]

r <-Partition(A,left,right)

k <-r-p+1

if(I==k)

return A[r]

if(I<k)

return SelectK(A,left,r-1,i)

else return SelectK(A,r+1,right,i-k)

什么意思呢,Partition就是快排序里的一步,我们找基准点,然后Partition后知道左边的数小于Partition,也就是说Partition后

基准点到了第i个大的位置(这里就是快排序的思想,不理解快排序的别看了,去看快排序)我们不在乎比基准点大的数的顺序

也不在乎比基准点小的顺序,但是我们知道了基准点到了第i个大的位置,接下来我们只要找到第k个大的就行了po上代码

int Select(int *nums,int left,int right,int i){    if(left==right)    {        return nums[left];    }    int r=Partition(nums,left,right);    int k=r-left+1;    if(i==k)    {        return nums[r];    }    else if(i<k)    {        Select(nums,left,r-1,i);    }    else    {        Select(nums,r+1,right,i-k);    }    return ;}int Partition(int *nums,int left,int right){    int pivot=nums[left];    int i=left;    int j=right;    if(i>j)    {        return ;    }    while(i!=j)    {        while(nums[j]>=pivot&&i<j)        {            j--;        }        while(nums[i]<=pivot&&i<j)        {            i++;        }        if(i<j)        {            nums[i]=nums[i]^nums[j];            nums[j]=nums[i]^nums[j];            nums[i]=nums[i]^nums[j];        }    }    nums[left]=nums[i];    nums[i]=pivot;    return i;}int findKthLargest(int* nums, int numsSize, int k){    int res=-1;    res=Select(nums,0,numsSize-1,numsSize-k+1);    return res;}
代码严格按照伪代码书写,跑完的速度为19ms,当然我们还可以更快(随机Select应该更快--和随机快排序一个道理,然而题主╮(╯▽╰)╭

那么这次各位看官就到这里下次准备写Double hashing了(然而我并不确定⊙ω⊙)

额,我把随机快排序调试出来了,尴尬,思路一直是对的,可是没有判断,大家也要注意,顺便网上你搜的随机快排序都是没有判读的,不过代码结构跟我一不一样偶就不晓得了

还是比较兴奋的po出代码,正好大家也看看随机select快多少

int Select(int *nums,int left,int right,int i){    if(left==right)    {        return nums[left];    }    int r=Partition(nums,left,right);    int k=r-left+1;    if(i==k)    {        return nums[r];    }    else if(i<k)    {        Select(nums,left,r-1,i);    }    else    {        Select(nums,r+1,right,i-k);    }    return ;}int Partition(int *nums,int left,int right){    int random=rand()%(right-left+1)+left;    if(random>left&&random<right)    {        nums[random]=nums[random]^nums[left];        nums[left]=nums[random]^nums[left];        nums[random]=nums[random]^nums[left];    }    int pivot=nums[left];    int i=left;    int j=right;    if(i>j)    {        return ;    }    while(i!=j)    {        while(nums[j]>=pivot&&i<j)        {            j--;        }        while(nums[i]<=pivot&&i<j)        {            i++;        }        if(i<j)        {            nums[i]=nums[i]^nums[j];            nums[j]=nums[i]^nums[j];            nums[i]=nums[i]^nums[j];        }    }    nums[left]=nums[i];    nums[i]=pivot;    return i;}int findKthLargest(int* nums, int numsSize, int k){    int res=-1;    res=Select(nums,0,numsSize-1,numsSize-k+1);    return res;}
最后6ms完成任务-.-然后我也不知道3ms的大牛是怎么做到的,但是这题我已经做的很细了

这回不出意外真是最后了

那么这题就这样


原创粉丝点击