leedcode215 数组中第k大的元素

思路参考:https://blog.csdn.net/love905661433/article/details/84930799

方法一:类似于冒泡法,取最后一个为基准,从前向后遍历,比基准数大就交换。

              一次遍历完成之后,基准数位置减一,开始第二次比较。

             重复k次,即可求得第k大元素。

方法二:参考自上述网址,采用三路快排。选取标定点,将数组分为比标定点大,和标定点相等,比标定点小三个部分。

定义两个指针sm,bi,和一个当前位置指针,则arr[0,sm]比标定点大,arr[sm+1,i-1]表示和标定点相等,arr[bi,n-1]表示比标定点小。判断排序后的标定点是否是第k大元素,如果不是,且比k大,则在比标定点大的范围内继续划分;比k小,在比标定点小的范围继续划分。

如果排成了从小打到的数组,则将k变为n-k+1代入即可。

时间复杂度:不太会计算,待求

swap(nums[lf], nums[mid]);这一步应该可以不要,不知道为何要加

#include<iostream>
#include<cassert>
#include<vector>

using namespace std;

class Solution1 {
public:
	int findKthLargest(vector<int>& nums, int k) {
		int left = 0;
		int right = nums.size() - 1;
		return  partitionK(nums, left, right, nums.size() - k + 1);

	}

	int partitionK(vector<int>& nums, int lf, int rg, int targ) {
		int i = lf;
		int sm = lf - 1;
		int bi = rg + 1;
		int mid = lf + (rg - lf) / 2;
		int im = nums[mid];
		swap(nums[lf], nums[mid]);

		while (i < bi) {

			if (nums[i] < im) {
				swap(nums[i], nums[sm + 1]);
				sm++;
				i++;
			}
			else if (nums[i] > im) {
				swap(nums[i], nums[bi - 1]);
				bi--;
			}
			else {
				assert(nums[i] == im);
				i++;
			}
		}

		if (targ - 1 <= sm)
			return partitionK(nums, lf, sm, targ);
		else if (targ - 1 >= bi)
			return partitionK(nums, bi, rg, targ);
		else
			return nums[targ - 1];
	}
};

class Solution2 {
public:
	int findKthLargest(vector<int>& nums, int k) {
		int left = 0;
		int right = nums.size() - 1;
		return  partitionK(nums, left, right, k);

	}

	int partitionK(vector<int>& nums, int lf, int rg, int targ) {
		int i = lf;
		int sm = lf - 1;
		int bi = rg + 1;
		int mid = lf + (rg - lf) / 2;
		int im = nums[mid];
		//swap(nums[lf], nums[mid]);

		while (i < bi) {

			if (nums[i] > im) {
				swap(nums[i], nums[sm + 1]);
				sm++;
				i++;
			}
			else if (nums[i] < im) {
				swap(nums[i], nums[bi - 1]);
				bi--;
			}
			else {
				assert(nums[i] == im);
				i++;
			}
		}

		if (targ - 1 <= sm)
			return partitionK(nums, lf, sm, targ);
		else if (targ - 1 >= bi)
			return partitionK(nums, bi, rg, targ);
		else
			return nums[targ - 1];
	}
};

int main(int argc, char** argv)
{
	int A[] = {3,2,1,5,6,4};
	vector<int> vec1(A, A+sizeof(A)/sizeof(int));
	int result1;
	
	result1 = Solution2().findKthLargest(vec1, 2);
	cout << result1 << endl;

	return 0;
}

方法三:使用堆, 维护一个元素个数为k的最大堆, 将所有数字放入到最大堆中, 全部放完之后, 最大堆中最小的那个元素就是第k个最大的元素。 这个方法以后再尝试。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值