【LeetCode & 剑指offer刷题】查找与排序题2:40 最小的k个数(对应Kth Largest Element in an Array)...

【LeetCode & 剑指offer刷题】查找与排序题2:40 最小的k个数(对应Kth Largest Element in an Array)

【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

40 最小的k个数

题目描述

输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,
 
/*
//暴力法:sort, O(nlogn)
//方法一:使用自带的stl函数
#include <algorithm>
using namespace std;
class Solution
{
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k)
    {
        if(k<=0 || k > input.size()) return vector<int>(); //处理非法输入
        nth_element(input.begin(), input.begin()+k-1, input.end());
        vector<int> result(input.begin(),input.begin()+k); //构造结果向量
        return result;
    }
};*/
/*
/*掌握
方法一:基于partition函数(快排中有用到,stl中也有,但是还是自己实现较好)
多次partition直到枢轴位置为k即可
缺点:会改变输入数组的元素位置
平均O(n),每次partition 平均O(n),次数未知,真的是O(n)吗,存疑?
思考:最好情况为O(n),最坏情况为O(n^2)(如对于倒序排列的数组)
通过优化partition,比如三数中值枢轴法或随机初始化枢轴法,可以改善时间复杂度
 
分析参考:
考虑最坏情况下,每次 partition 将数组分为长度为 N-1 和 1 的两部分,然后在长的一边继续寻找第 K 大,此时时间复杂度为 O(N^2 )。
不过如果在开始之前将数组进行随机打乱,那么可以尽量避免最坏情况的出现。
而在最好情况下,每次将数组均分为长度相同的两半,运行时间 T(N) = N + T(N/2),时间复杂度是 O(N)。
*/
#include <cstdlib>
class Solution
{
public :
    vector < int > GetLeastNumbers_Solution ( vector < int > input , int k )
    {
       if ( input . empty () || k <= 0 || k > input . size ()) return vector < int >(); //处理异常输入
      
        int left = 0 , right = input . size ()- 1 ;
        int pivot_pos ;
        while ( left <= right ) //类似二分查找法
        {
            pivot_pos = partition ( input , left , right ); //如果要求最大的第k个数,可以对partition函数进行改造
            if ( pivot_pos < k - 1 )
                left = pivot_pos + 1 ;
            else if ( pivot_pos > k - 1 )            
                right = pivot_pos - 1 ;
             else
                 break ; //此题要求的是返回最小的前k个数,如果仅返回最小的第k个数,直接在这里return a[pivot_pos]即可
                
        }
        vector < int > result ( input . begin (), input . begin ()+ k ); //构造结果向量
        return result ;
    }
private :
    int partition ( vector < int >& a , int left , int right )
    {
        //随机初始化枢轴 5ms
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值