【LeetCode】215.Kth Largest Element in an Array(数组中的第K个最大元素)-快速排序法-C++实现

本题是一道经典的算法题,也是facebook、MicroSoft、amazon、Bloomberg、Apple的面试题。

问题描述:

(1)首先,我们定义一个随机数组,查找数组中第二大的元素:

	vector<int> nums1 = { 3, 2, 1, 5, 6, 4 };
	cout << Solution().findKthLargest(nums1, 2) << endl;

(2)对数组进行排序,使的数组由大到小排列,下标为k-1的元素即为数组中第k大元素

public:
	int findKthLargest(vector<int>& nums, int k) {
		return __findKthLargest(nums, 0, nums.size() - 1, k - 1);
	}

(3)函数__findKthLargest

private:
	int __findKthLargest(vector<int>& nums, int l, int r, int k) {

		if (l == r)
			return nums[l];

		int p = partition(nums, l, r);

		if (p == k)
			return nums[p];
		else if (k < p)
			return __findKthLargest(nums, l, p - 1, k);
		else // k > p
			return __findKthLargest(nums, p + 1, r, k);
	}

(4)函数partition()的实现-使用快速排序法

type:

我们选择一个随机数组 { 3, 2, 1, 5, 6, 4 },选择第一个元素为标定点 p = 3;

 定义慢指针int lt = l + 1;

快指针:int i = l + 1;

遍历数组

第一轮遍历:

① if (nums[i] <= nums[l])
               则i++;

②            if (nums[i] > nums[l])
                swap(nums[i], nums[lt]); 

然后Lt++,i++

遍历完成后:

 最后,swap(nums[l], nums[lt - 1]);

 return lt - 1;

所以,函数partition返回3。

此时 p = 3,k = 1;

if (k < p)
            return __findKthLargest(nums, l, p - 1, k);

进行第二轮遍历:

遍历完成后的到的数组

return lt - 1;       所以p =2 .

进行第三轮遍历:

 

遍历完成后:

     return lt - 1; 所以 p = 0;  

if(k > p)
            return __findKthLargest(nums, p + 1, r, k);

此时,__findKthLargest(nums,1, 1, 1)

   所以:     if (l == r)
            return nums[l];   

nums[1] = 5;

完成了整个数组的查找!

 

完整的源代码:

#include <iostream>
#include <vector>
#include <cassert>
#include <stdexcept>
#include <ctime>

using namespace std;


/// Quick Sort Partition.
/// Time Complexity:  O(n)
/// Space Complexity: O(1)
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {

        srand(time(NULL));
        return __findKthLargest(nums, 0, nums.size()-1 , k - 1 );
    }

private:
    int __findKthLargest( vector<int>& nums, int l, int r, int k ){

        if( l == r )
            return nums[l];

        int p = partition( nums, l, r );

        if( p == k )
            return nums[p];
        else if( k < p )
            return __findKthLargest( nums, l, p-1, k);
        else // k > p
            return __findKthLargest( nums, p+1 , r, k );
    }

    int partition( vector<int>& nums, int l, int r ){

        int p = rand()%(r-l+1) + l;
        swap( nums[l] , nums[p] );

        int lt = l + 1; //[l+1...lt) > p ; [lt..i) < p
        for( int i = l + 1 ; i <= r ; i ++ )
            if( nums[i] > nums[l] )
                swap(nums[i], nums[lt++]);

        swap(nums[l], nums[lt-1]);

        return lt-1;
    }
};


int main() {

    vector<int> nums1 = {3, 2, 1, 5, 6, 4};
    cout << Solution().findKthLargest(nums1, 2) << endl;

    vector<int> nums2 = {3, 1, 2, 4};
    cout << Solution().findKthLargest(nums2, 2) << endl;

    vector<int> nums3 = {3, 3, 3, 3, 3, 3, 3, 3, 3};
    cout << Solution().findKthLargest(nums3, 8) << endl;

    return 0;
}

<全文完>

参考资料:

  https://github.com/liuyubobobo/Play-Leetcode

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值