《leetCode》:Kth Largest Element in an Array

题目

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大的元素即可。但是,时间复杂度为O(n*logn)

int cmp(const void* a,const void* b){
    return  (*((int *)a))-(*((int *)b));
}

int findKthLargest(int* nums, int numsSize, int k) {
    if(nums==NULL||numsSize<1||k<0||k>numsSize){
        return 0;
    }
    qsort(nums,numsSize,sizeof(nums[0]),cmp);
    return nums[numsSize-k];
}

思路二:不完全排序

思路一是全部将数组进行了排序然后选择出结果。其实,我们可以选择不完全排序来解决问题,在快排中,将数组分成两半,前面一半数组中的数全部小于 主元的值,后面一半数组中的数全部大于主元的值,如果主元的索引index

void swap(int *a,int *b){
    int temp=*a;
    *a=*b;
    *b=temp;
}
int partition(int* nums, int start,int end){
    if(end<start){
        return -1;
    }
    int val=nums[start];
    int index=start;
    for(int i=start+1;i<=end;i++){
        if(nums[i]<val){
            index++;
            swap(&nums[index],&nums[i]);
        }
    }
    swap(&nums[start],&nums[index]);
    return index;
}

void sortHelper(int* nums, int start,int end,int numsSize,int k){
    if(end<=start){
        return;
    }
    int index=partition(nums,start,end);
    if(index==numsSize-k){
        return;
    }
    else if(index<numsSize-k){
        sortHelper(nums,index+1,end,numsSize,k);
    }
    else if(index>numsSize-k){
        sortHelper(nums,start,index-1,numsSize,k);
    }
}

int findKthLargest(int* nums, int numsSize, int k) { 
    if(nums==NULL||numsSize<1||k<0||k>numsSize){
        return 0;
    } 
    int start=0;
    int end=numsSize-1;
    sortHelper(nums,start,end,numsSize,k);
    return nums[numsSize-k];
}

通过上面的理论分析,理论上第二种方法的运行时间会比第一种的运行时间少,出于好奇的看了下这两种方法的运行时间,如下:

第一种方法的运行时间:

第二种方法的运行时间:

从两张图中可以看出,居然是第一种的还要快。比较郁闷,居然和理论结果不一样。
郁闷的同时也开始找原因,开始以为是因为函数调用开销太大,导致第二种方法的运行时间过慢,因此,就把swap(int *a,int *b) 的功能全部用三行代码在函数partition中实现。居然,根本没有改善。呜呜。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值