C++面试题(25)------最小的k个数

  • 操作系统:ubuntu22.04
  • IDE:Visual Studio Code
  • 编程语言:C++11

题目描述

输入整数数组 arr,求出其中最小的 k 个数。
你可以按任意顺序返回这 k 个数。

示例:

输入:arr = [3,2,1], k = 2
输出:[1,2][2,1]

输入:arr = [0,1,2,1], k = 1
输出:[0]

解法一:排序取前k个(简单直观)

思路:

对数组进行排序,然后取前 k 个元素即可。
C++ 实现:

#include 
#include 

std::vector<int> findK(std::vector<int> nums, int k)
{
    std::sort(nums.begin(), nums.end());

    return std::vector<int>(nums.begin(), nums.begin()+k); 
}

int main()
{
    std::vector<int> nums = {1,2,3,5,6,1,2};

    std::vector<int> res = findK(nums, 3);

    for(int i:res)
    {
        std::cout<< i <<",";
    }
   
}

解法二:大根堆(优先队列)优化(适合海量数据)

使用一个**最大堆(priority_queue)**来维护当前最小的 k 个数:

  • 堆大小保持为 k
  • 每次插入新元素时,如果堆已满且当前元素比堆顶小,则弹出堆顶并插入当前元素
  • 最终堆中就是最小的 k 个数
#include 
#include 

using namespace std;

class Solution {
public:
    vector< int > getLeastNumbers( vector< int >& arr, int k )
    {
        if ( k == 0 || arr.empty() )
            return {};

        // 大根堆定义方式:默认是最大堆
        priority_queue< int > maxHeap;

        for ( int num : arr )
        {
            if ( maxHeap.size() < k )
            {
                maxHeap.push( num );
            }
            else if ( num < maxHeap.top() )
            {
                maxHeap.pop();
                maxHeap.push( num );
            }
        }

        // 将堆中元素放入结果数组
        vector< int > res;
        while ( !maxHeap.empty() )
        {
            res.push_back( maxHeap.top() );
            maxHeap.pop();
        }

        return res;
    }
};

解法三:快速选择算法(最优解,适合进阶)

这是本题的最优解法,利用快排思想,平均时间复杂度 O(n),空间复杂度 O(1)(原地分区)
核心思想:

  • 类似于快排的 partition 操作,将数组分为两部分;
  • 如果 pivot 的位置正好是 k,那么前 k 个元素就是最小的 k 个数;
  • 否则根据 pivot 的位置递归处理左右部分。

代码:

#include 
#include 

using namespace std;

class Solution {
private:
    int partition(vector<int>& arr, int left, int right) {
        int pivot = arr[right];
        int i = left;
        for (int j = left; j < right; ++j) {
            if (arr[j] <= pivot) {
                swap(arr[i++], arr[j]);
            }
        }
        swap(arr[i], arr[right]);
        return i;
    }

    void quickSelect(vector<int>& arr, int left, int right, int k) {
        if (left >= right) return;

        int pivotIndex = partition(arr, left, right);
        if (pivotIndex == k) return;
        else if (pivotIndex > k) quickSelect(arr, left, pivotIndex - 1, k);
        else quickSelect(arr, pivotIndex + 1, right, k);
    }

public:
    vector<int> getLeastNumbers(vector<int>& arr, int k) {
        if (k == 0 || arr.empty()) return {};
        if (k >= arr.size()) return arr;

        quickSelect(arr, 0, arr.size() - 1, k);

        return vector<int>(arr.begin(), arr.begin() + k);
    }
};

你可能感兴趣的:(c++,c++,算法,开发语言)