LeetCode 215.数组中的第K个最大元素(四种排序算法)

方法一:冒泡排序返回倒数第K个元素

class Solution {
    public int findKthLargest(int[] nums, int k) {
        int n = nums.length,temp;
        for (int i = 0; i < n - 1; i++) {
			for (int j = 0; j < n - i - 1; j++) {
				if (nums[j] > nums[j + 1]) {
					temp = nums[j];
					nums[j] = nums[j + 1];
					nums[j + 1] = temp;
				}
			}
		}
        return nums[n-k];
    }
}

方法二 快速排序:

class Solution {
	int Partition(int[] A, int low, int high) {
		int pivot = A[low];
		while (low < high) {
			while (low < high && A[high] >= pivot)
				--high;
			A[low] = A[high];// 将比枢轴小的元素移动到左端
			while (low < high && A[low] <= pivot)
				++low;
			A[high] = A[low];// 将比枢轴大的元素移动到右端
		}
		A[low] = pivot;// 枢轴元素存放到最终位置
		return low;// 返回存放枢轴的最终位置
	}

	void QuickSort(int[] A, int low, int high) {
		if (low < high) {// 递归跳出条件 下面一个方法可以没有这句话
			int pivot = Partition(A, low, high);// 划分
			QuickSort(A, low, pivot - 1);
			QuickSort(A, pivot + 1, high);
		}
	}

	public int findKthLargest(int[] nums, int k) {
		int n = nums.length;
		QuickSort(nums, 0, n - 1);
		return nums[n - k];
	}
}

方法三 快速选择排序:

利用一趟快速排序可以确定一个元素的最终位置,只需要找到最终位置就可以了,所以不需要全排序完

class Solution {
	int Partition(int[] A, int low, int high) {
		int pivot = A[low];
		while (low < high) {
			while (low < high && A[high] >= pivot)
				--high;
			A[low] = A[high];// 将比枢轴小的元素移动到左端
			while (low < high && A[low] <= pivot)
				++low;
			A[high] = A[low];// 将比枢轴大的元素移动到右端
		}
		A[low] = pivot;// 枢轴元素存放到最终位置
		return low;// 返回存放枢轴的最终位置
	}

	int QuickSort(int[] A, int low, int high, int k) {
		int pivot = Partition(A, low, high);// 划分
		if (pivot < A.length - k) {//最终位置在枢轴右边->到枢轴右边找
			return QuickSort(A, pivot + 1, high, k);
		} else if (pivot == A.length - k) {
			return pivot;//递归跳出条件
		} else {//最终位置在枢轴左边->到枢轴左边找
			return QuickSort(A, low, pivot - 1, k);
		}

	}

	public int findKthLargest(int[] nums, int k) {
		int n = nums.length;
		QuickSort(nums, 0, n - 1, k);
		return nums[n - k];
	}
}

方法四 堆排序 优化 只排了前k个最大的元素

class Solution {
    
	void BuildMaxHeap(int[] A, int length) {// 建堆
		for (int i = length / 2; i >= 0; i--) {
			HeadAdjust(A, i, length);
		}
	}

	void HeadAdjust(int[] A, int k, int length) {// 和王道不一样下标从0开始算
		// 函数HeadAdjust将元素为k的子树进行调整
		int temp = A[k];// temp暂存子树根结点
		for (int i = 2 * k + 1; i <= length - 1; i = i * 2 + 1) {// 从k的第一个孩子2k+1开始比较
			if (i + 1 < length && A[i] < A[i + 1])// 如果右孩子大
				i++;
			if (temp > A[i])// 根最大不用调整,上面i++后的话,现在的A[i]就是刚才的i+1
				break;
			else {
				A[k] = A[i];// 将A[i]调整到双亲结点上
				k = i;// 将i赋值给k,现在的k就是刚才的孩子结点
			}
		}
		A[k] = temp;// 双亲结点调整到孩子结点
	}

	void HeapSort(int[] A, int length,int k) {
		BuildMaxHeap(A, length);// 先建堆

		for (int i = length - 1; i >= length-k; i--) {//只输出前k个堆顶
			int temp = A[0];// 堆顶和最后一个元素交换
			A[0] = A[i];
			A[i] = temp;
			HeadAdjust(A, 0, i);// 调整堆
		}
	}
    public int findKthLargest(int[] nums, int k) {
        HeapSort(nums,nums.length,k);
        return nums[nums.length-k];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值