• 最小的K个数 C++(BFPRT,堆排序)


    题目描述

    输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
    //堆排序
    #include <iostream>
    #include <algorithm>
    #include <vector>
    using namespace std;
    class Solution
    {
    public:
        void HeapAdjust(vector<int> &a,int s,int n)
        {
            int rc=a[s];
            for(int j=2*s+1; j<=n-1; j=j*2+1)
            {
                if(j<n-1&&a[j]>a[j+1])
                    j++;
                if(rc<=a[j])
                    break;
                else
                {
                    a[s]=a[j];
                    s=j;
                }
            }
            a[s]=rc;
        }
        void CreatHeap(vector<int> &a,int n)
        {
            for(int i=n/2-1; i>=0; i--)
            {
                HeapAdjust(a,i,n);
            }
        }
       vector<int> GetLeastNumbers_Solution(vector<int> input, int k)
        {
            vector<int> ans;
            if(input.size()==0||k==0||k>input.size())
                return ans;
            int n=input.size();
            CreatHeap(input,n);
            for(int i=n-1; i>0; i--)
            {
                    int x=input[0];
                    input[0]=input[i];
                    input[i]=x;
                    HeapAdjust(input,0,i);
            }
            for(int i=input.size()-1;i>=0&&k>0;i--)
            {
                ans.push_back(input[i]);
                k--;
            }
            return ans;
        }
    };
    int main()
    {
        Solution s;
        int k=4;
        vector<int> ans;
        vector<int> input;
        input.push_back(4);
        input.push_back(5);
        input.push_back(1);
        input.push_back(6);
        input.push_back(2);
        input.push_back(7);
        input.push_back(3);
        input.push_back(8);
        ans=s.GetLeastNumbers_Solution(input,k);
        for(int i=0; i<ans.size(); i++)
        {
            cout<<ans[i];
        }
    
    
        return 0;
    }
    //BFPRT
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    using namespace std;
    class Solution {
    public:
        vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
            vector<int> ans;
            if(input.size()==0||k==0||k>input.size())
            {
                return ans;
            }
            for(int i=0; i<=BFPRT(input,0,input.size()-1,k); i++)
            {
                ans.push_back(input[i]);
            }
            return ans;
        }
        /* 插入排序,返回中位数下标 */
        int InsertSort(vector<int> &array, int left, int right)
        {
            int temp;
            int j;
            for (int i = left + 1; i <= right; i++)
            {
                temp = array[i];
                j = i - 1;
                while (j >= left && array[j] > temp)
                    array[j + 1] = array[j--];
                array[j + 1] = temp;
            }
    
            return ((right - left) >> 1) + left;
        }
    
        /* 返回中位数的中位数下标 */
        int GetPivotIndex(vector<int> &array, int left, int right)
        {
            if (right - left < 5)
                return InsertSort(array, left, right);
    
            int sub_right = left - 1;
            for (int i = left; i + 4 <= right; i += 5)
            {
                int index = InsertSort(array, i, i + 4);  //找到五个元素的中位数的下标
                swap(array[++sub_right], array[index]);   //依次放在左侧
            }
    
            return BFPRT(array, left, sub_right, ((sub_right - left + 1) >> 1) + 1);
        }
    
        /* 利用中位数的中位数的下标进行划分,返回分界线下标 */
        int Partition(vector<int> &array, int left, int right, int pivot_index)
        {
            swap(array[pivot_index], array[right]);  //把基准放置于末尾
    
            int divide_index = left;  //跟踪划分的分界线
            for (int i = left; i < right; i++)
            {
                if (array[i] < array[right])
                    swap(array[divide_index++], array[i]);  //比基准小的都放在左侧
            }
    
            swap(array[divide_index], array[right]);  //最后把基准换回来
            return divide_index;
        }
    
        int BFPRT(vector<int> &array, int left, int right, const int & k)
        {
            int pivot_index = GetPivotIndex(array, left, right);            //得到中位数的中位数下标
            int divide_index = Partition(array, left, right, pivot_index);  //进行划分,返回划分边界
            int num = divide_index - left + 1;
            if (num == k)
                return divide_index;
            else if (num > k)
                return BFPRT(array, left, divide_index - 1, k);
            else
                return BFPRT(array, divide_index + 1, right, k - num);
        }
    };
    int main()
    {
        Solution s;
        int k=4;
        vector<int> ans;
        vector<int> input;
        input.push_back(4);
        input.push_back(5);
        input.push_back(1);
        input.push_back(6);
        input.push_back(2);
        input.push_back(7);
        input.push_back(3);
        input.push_back(8);
        ans=s.GetLeastNumbers_Solution(input,k);
        for(int i=0; i<ans.size(); i++)
        {
            cout<<ans[i];
        }
    
    
        return 0;
    }
  • 相关阅读:
    近来无聊 写了一个google音乐的下载器
    HTML编辑器 HtmlArea
    Html编辑器 TinyMCE
    IE浏览器自定义地址协议 通过B/S程序中打开C/S程序
    html 元素的 onpropertychange 事件
    asp.net 服务器控件防止重复提交表单
    用 BindingSource 绑定窗体中控件不失去焦点无法更新数据源的问题
    动态创建大量 html dom 元素时提升性能
    很黄的日期格式化。。。
    Asp.net 导出 .html,.txt 等格式的文件
  • 原文地址:https://www.cnblogs.com/dshn/p/9426931.html
Copyright © 2020-2023  润新知