zoukankan      html  css  js  c++  java
  • 求最小的K个数

    方法一:利用快排的思想,复杂度为O(n)???

    class Solution {
    public:
        int Partition(vector<int>& input, int begin, int end)
    {
        int low = begin;
        int high = end;
    
        int pivot = input[low];
        while (low<high)
        {
            while (low<high&&pivot <= input[high])
                high--;
            //input[low] = input[high];
            swap(input[low], input[high]);
            while (low<high&&pivot >= input[low])
                low++;
            //input[high] = input[low];
            swap(input[low], input[high]);
        }
        input[low] = pivot;
        return low;
    }
    
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
    
        int len = input.size();
        if (len == 0 || k>len||k<=0) return vector<int>();
        if (len == k) return input;
    
        int start = 0;
        int end = len - 1;
        int index = Partition(input, start, end);
        while (index != (k - 1))
        {
            if (index>k - 1)
            {
                end = index - 1;
                index = Partition(input, start, end);
            }
            else
            {
                start = index + 1;
                index = Partition(input, start, end);
            }
        }
    
        vector<int> res(input.begin(), input.begin() + k);
    
        return res;
        }
    };

     方法二:利用堆排序的思想,时间复杂度为O(nlogk)

    利用堆排序,特别适用于海量数据中寻找最大或者最小的k个数字。即构建一个大堆容器,初始化大小为k,变量初始数,如初始数组大小小于等于k直接返回,如果大于k,则选择数组的前k个元素,填充堆,然后调整为最大堆。调整完之后,继续从初始数组中拿出一个元素,如果该元素比大堆的堆顶小,则替换堆顶,继续调整为最大堆,如果大于等于堆顶则直接丢弃,不作调整。 
    PS:大堆还是小堆的选择很重要,不是寻找最小的k个元素就要选择小堆,而且恰恰相反。寻找最小的k个数,其实就是寻找第k个大的元素,即寻找k个数中最大的,不断调整堆,堆得元素个数是k,堆顶是最大值,遍历完初始数组后,堆中存在的元素即使我们所要寻找的k个最小元素。

    class Solution {
    public:
        vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {if(k<=0||k>input.size()||input.size()==0)return vector<int>();
            vector<int>max_heap(k,0);
            for(int i=0;i<k;i++){
                max_heap[i]=input[i];
            }
            for(int i=(k-1)/2;i>=0;i--)
                maxheap_down(max_heap,i,k-1);
            for(int i=k;i<input.size();i++){
                if(input[i]<max_heap[0]){
                    max_heap[0]=input[i];
                    maxheap_down(max_heap,0,k-1);
                }
            }
            return max_heap;
        }
        
        void maxheap_down(vector<int>&a,int start,int end){
            int c=start;
            int value=a[c];
            int l=2*c+1;
            for(;l<=end;c=l,l=2*c+1){
                if(l<end&&a[l]<a[l+1])l++;
                if(value>a[l])break;
                else{
                    a[c]=a[l];
                    a[l]=value;
                }
            }
        }
    };
  • 相关阅读:
    Haskell 差点儿无痛苦上手指南
    蛋疼的Apple IOS Push通知协议
    css概述
    数据挖掘十大经典算法
    序员工作究竟能干多久?程序猿的前途怎样?
    怎样将程序猿写出来的程序打包成安装包(最简单的)
    Denny Zhang:一辈子做一个自由职业者
    自己动手写操作系统--个人实践
    结构体数组
    英雄会挑战失败求原因
  • 原文地址:https://www.cnblogs.com/inception6-lxc/p/9058433.html
Copyright © 2011-2022 走看看