215. 数组中的第K个最大元素

1. 题号和题目名称

  1. 数组中的第K个最大元素

2. 题目叙述

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O ( n ) O(n) O(n) 的算法解决此问题。

3. 模式识别

本题的核心是在无序数组中找出第 k 大的元素。可以联想到排序相关的算法,不过要满足 O ( n ) O(n) O(n) 时间复杂度,需要使用一些特殊的算法,如快速选择算法或堆排序。

4. 考点分析

  • 排序算法的理解:对常见排序算法(如快速排序、堆排序)的原理和复杂度有深入理解。
  • 分治思想:快速选择算法基于分治思想,需要掌握分治算法的设计和实现。
  • 数据结构的运用:堆排序需要使用堆这种数据结构,要理解堆的性质和操作。

5. 所有解法

解法一:排序法

将数组进行排序(如使用快速排序、归并排序等),然后直接返回第 k 大的元素。这种方法的时间复杂度为 O ( n l o g n ) O(n log n) O(nlogn),不满足题目要求的 O ( n ) O(n) O(n) 复杂度。

解法二:堆排序

使用堆来维护前 k 大的元素。可以使用最小堆,遍历数组,将元素依次加入堆中,当堆的大小超过 k 时,移除堆顶元素(最小元素)。最后堆顶元素即为第 k 大的元素。时间复杂度为 O ( n l o g k ) O(n log k) O(nlogk)

解法三:快速选择算法

这是本题的最优解法。快速选择算法基于快速排序的思想,通过选择一个基准元素,将数组分为两部分,根据基准元素的位置和 k 的大小关系,决定在左半部分或右半部分继续查找,平均时间复杂度为 O ( n ) O(n) O(n)

6. 最优解法(快速选择算法)的 C 语言代码

#include <stdio.h>

// 交换两个元素的函数
void swap(int *a, int *b) {
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

// 快速选择函数,用于查找第 k 小的元素
int quickselect(int *nums, int l, int r, int k) {
    if (l == r)
        return nums[l];  // 修正此处,返回 nums[l]
    int partition = nums[l];
    int i = l - 1, j = r + 1;
    while (i < j) {
        do i++; while (nums[i] < partition);
        do j--; while (nums[j] > partition);
        if (i < j) {
            swap(&nums[i], &nums[j]);
        }
    }
    if (k <= j)
        return quickselect(nums, l, j, k);
    else
        return quickselect(nums, j + 1, r, k);
}

// 查找第 k 大的元素
int findKthLargest(int *nums, int numsSize, int k) {
    return quickselect(nums, 0, numsSize - 1, numsSize - k);
}

7. 复杂度分析

  • 时间复杂度:平均情况下为 O ( n ) O(n) O(n),最坏情况下为 O ( n 2 ) O(n^2) O(n2)。在每次分区操作中,能够将问题规模大致缩小一半,因此平均时间复杂度为线性。
  • 空间复杂度:平均情况下为 O ( l o g n ) O(log n) O(logn),最坏情况下为 O ( n ) O(n) O(n)。主要的空间开销在于递归调用栈的深度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

请向我看齐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值