解题思路
这是一道经典的第 大数问题,有多种解法:
-
排序法:
- 将数组排序后直接返回第
大的数
- 时间复杂度
- 空间复杂度
- 将数组排序后直接返回第
-
快速选择法(最优解):
- 基于快速排序的思想
- 每次只需要处理一半的数据
- 时间复杂度
- 空间复杂度
-
堆排序法:
- 维护一个大小为
的小顶堆
- 时间复杂度
- 空间复杂度
- 维护一个大小为
代码
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
return quickSelect(nums, 0, nums.size() - 1, k);
}
private:
int quickSelect(vector<int>& nums, int left, int right, int k) {
int pivot = partition(nums, left, right);
// 找到第K大的数
if (pivot == nums.size() - k) {
return nums[pivot];
}
// 在右半部分查找
else if (pivot < nums.size() - k) {
return quickSelect(nums, pivot + 1, right, k);
}
// 在左半部分查找
else {
return quickSelect(nums, left, pivot - 1, k);
}
}
int partition(vector<int>& nums, int left, int right) {
int pivot = nums[right];
int i = left;
for (int j = left; j < right; j++) {
if (nums[j] <= pivot) {
swap(nums[i], nums[j]);
i++;
}
}
swap(nums[i], nums[right]);
return i;
}
};
int main() {
int n;
vector<int> nums;
int num;
// 读入数组
while (cin >> num) {
nums.push_back(num);
if (cin.get() == '\n') break;
}
// 读入K
int k;
cin >> k;
Solution solution;
cout << solution.findKthLargest(nums, k) << endl;
return 0;
}
import java.util.*;
public class Main {
public static int findKthLargest(int[] nums, int k) {
return quickSelect(nums, 0, nums.length - 1, k);
}
private static int quickSelect(int[] nums, int left, int right, int k) {
int pivot = partition(nums, left, right);
if (pivot == nums.length - k) {
return nums[pivot];
}
else if (pivot < nums.length - k) {
return quickSelect(nums, pivot + 1, right, k);
}
else {
return quickSelect(nums, left, pivot - 1, k);
}
}
private static int partition(int[] nums, int left, int right) {
int pivot = nums[right];
int i = left;
for (int j = left; j < right; j++) {
if (nums[j] <= pivot) {
swap(nums, i, j);
i++;
}
}
swap(nums, i, right);
return i;
}
private static void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] input = sc.nextLine().split(" ");
int[] nums = new int[input.length];
for (int i = 0; i < input.length; i++) {
nums[i] = Integer.parseInt(input[i]);
}
int k = sc.nextInt();
System.out.println(findKthLargest(nums, k));
}
}
def find_kth_largest(nums: list, k: int) -> int:
def quick_select(left: int, right: int, k: int) -> int:
pivot = partition(left, right)
if pivot == len(nums) - k:
return nums[pivot]
elif pivot < len(nums) - k:
return quick_select(pivot + 1, right, k)
else:
return quick_select(left, pivot - 1, k)
def partition(left: int, right: int) -> int:
pivot = nums[right]
i = left
for j in range(left, right):
if nums[j] <= pivot:
nums[i], nums[j] = nums[j], nums[i]
i += 1
nums[i], nums[right] = nums[right], nums[i]
return i
return quick_select(0, len(nums) - 1, k)
def main():
nums = list(map(int, input().split()))
k = int(input())
print(find_kth_largest(nums, k))
if __name__ == "__main__":
main()
算法及复杂度
- 算法:快速选择(Quick Select)
- 时间复杂度:
- 平均情况
- 空间复杂度:
- 原地操作