指offer系列22:最小的K个数

Posted neverland0718

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了指offer系列22:最小的K个数相关的知识,希望对你有一定的参考价值。

我的第一个思路就是用快排的方法做,找到下标为k 的数字。其中的细节多注意,特别是在快排的函数调用的时候。

 1 #include <iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 class Solution 
 7 public:
 8     //static int k;
 9     vector<int> GetLeastNumbers_Solution(vector<int> input, int k) 
10         vector<int> auxi;
11         int len = input.size();
12         int left=0,right=len-1;
13         if (k > len+ 1||len==0)
14             return auxi;
15         if (k <= 0)//开始没写这一句牛客判定超时?
16             return auxi;
17         if (k == len)
18             return input;
19         findx(input,left,right,k);
20         for (int i = 0; i < k; i++)
21         
22             auxi.push_back(input[i]);
23         
24         sort(auxi.begin(), auxi.end());
25         return auxi;
26 
27     
28     void findx(vector<int> &ve2, int low, int high,int n)
29     
30         int index = partition(ve2, low, high);//定义第一个数的下标为index
31                                                   //int true = k - 1;
32         while (index != n - 1)//找到下标为k的的数
33         
34             if (index > n - 1)//0,1,2,3
35             
36                 high = index - 1;
37                 index=partition(ve2,low,high);//这里的递归一定要弄清楚,是递归partition函数还是递归自己
38             
39             else
40             
41                 low = index + 1;
42                 index = partition(ve2, low,high);
43             
44         
45     
46     int partition(vector<int> &ve, int low, int high)//快排的函数,我上一个题中的函数写错了
47     
48         int sig = ve[low];
49         while (low < high)
50         
51             while (low < high&&sig <= ve[high])//从右开始找,如果右边的数比sig大,跳过
52                 high--;
53             //当高位的值比sig还小的时候,直接把高位的小值放到sig的位置去
54             ve[low] = ve[high];
55             while (low < high&&ve[low]<=sig)//从左开始找,如果左边的数比sig小,跳过
56                 low++;
57             //当低位的值比sig还大的时候,直接把低位的大值放到sig的位置去
58             ve[high] = ve[low];
59 
60         
61         ve[low] = sig;
62         return low;
63     
64 ;
65 int main()
66 
67     Solution so;
68     vector<int> test =  3,5,1,6,2,7,4,8 ;
69     vector<int> result;
70     result=so.GetLeastNumbers_Solution(test, 4);
71     for (int i = 0; i < result.size(); i++)
72     
73         cout << result[i] <<endl;
74     
75     return 0;
76 

第二种方法:在答案里看到的,由于我自己也不是很理解,所以没怎么写注释

 1 #include <iostream>
 2 #include<vector>
 3 #include<set>
 4 #include <functional>
 5 using namespace std;
 6 
 7 class Solution 
 8 public:
 9     vector<int> GetLeastNumbers_Solution(vector<int> input, int k) 
10         int len = input.size();
11         if (k>len || k <= 0)
12         
13             return vector<int>();
14         
15         multiset<int, greater<int>> leastnumbers;
16         vector<int>::iterator vec_it = input.begin();
17         for (; vec_it != input.end(); vec_it++)
18         
19             if (leastnumbers.size() < k)//如果容器不满,就直接插入
20                 leastnumbers.insert(*vec_it);
21             else
22             
23                 multiset<int, greater<int> >::iterator greateast_it = leastnumbers.begin();
24                 if (*vec_it < *(leastnumbers.begin()))//判断后面的数字是否大于容器中的最大数
25                 
26                     leastnumbers.erase(greateast_it);
27                     leastnumbers.insert(*vec_it);
28                 
29             
30         
31         return vector<int>(leastnumbers.begin(), leastnumbers.end());
32     
33 ;
34 int main()
35 
36     Solution so;
37     vector<int> test =  3,5,1,6,2,7,4,8 ;
38     vector<int> result;
39     result = so.GetLeastNumbers_Solution(test, 4);
40     for (int i = 0; i < result.size(); i++)
41     
42         cout << result[i] << endl;
43     
44     return 0;
45 

 

以上是关于指offer系列22:最小的K个数的主要内容,如果未能解决你的问题,请参考以下文章

剑指Offer对答如流系列 - 最小的k个数

剑指offer系列——剑指 Offer 22. 链表中倒数第k个节点(C语言)

剑指offer系列5:二进制中1的个数

剑指Offer对答如流系列 - 把数组排成最小的数

剑指offer系列58---把数组排成最小的数

剑指offer系列——32.把数组排成最小的数