【面试题】剑指Offer-30-最小的第K个数

来源:互联网 发布:java 微信语音聊天 编辑:程序博客网 时间:2024/05/21 18:42

题目概述


解题思路

方法1

将数组进行排序,排成升序

则最小的K个数便是数组的前K个数字了

方法2

利用快排的思想

利用单趟排序

如果排的数字是第K个位置

那么其以及其左边的数字就是前面最小的了

方法3

利用STL中的红黑树

这个和堆的思想是一样的

只是查找的时候用了begin()函数取到最大值

代码实现

方法1

//方法一//排序,排成升序//前K个数即为最小的前K个数字//快速排序//左右指针法int PartSort(int* arr,int left, int right){while (left < right){while (left < right && arr[left] <= arr[right])left++;while (left < right && arr[right] >= arr[left])right--; std::swap(arr[left], arr[right]);}return left;}void PrintMinKNums(int* arr, size_t n){cout << "最小的前 " << n << " 位数是:" << endl;for (size_t i = 0; i < n; ++i)cout << arr[i] << " ";cout << endl;}void QuickSort(int* arr, int left, int right){if (left < right){int mid = PartSort(arr, left, right);QuickSort(arr, left, mid - 1);QuickSort(arr, mid + 1, right);}}void TestFindMinKNums1(){int a[] = { 4, 5, 1, 6, 2, 7, 3, 8 };QuickSort(a, 0, sizeof(a) / sizeof(a[0])-1);PrintMinKNums(a, 4);}

方法2

//方法2//利用快排的思想,找到最小的那位(利用PartSort)void FindMinKNums2(int* arr,int left, int right,const int index){if (left < right){int mid = PartSort(arr, left, right);if (mid == (index - 1))return;else if (mid > (index-1))return FindMinKNums2(arr, left, mid - 1, index);elsereturn FindMinKNums2(arr, mid + 1, right, index);}}void TestFindMinKNums2(){int a[] = { 4, 5, 1, 6, 2, 7, 3, 8 };FindMinKNums2(a, 0, sizeof(a) / sizeof(a[0]) - 1, 4);PrintMinKNums(a, 4);}

方法3

//方法3//利用STL中的红黑树#include<set>struct greater{bool operator()(const int& i1, const int& i2){return i1 > i2;}};pair<bool, multiset<int, greater>> FindMinKNums3(int* arr, size_t n, int index){if (index < 1)return pair<bool, multiset<int, greater>>(false, multiset<int, greater>());multiset<int,greater> mSet;for (size_t i = 0; i < n; ++i){if (mSet.size() < index){mSet.insert(arr[i]);}else{if (arr[i] < *mSet.begin()){mSet.erase(mSet.begin());mSet.insert(arr[i]);}}}if (mSet.size() < index)return pair<bool, multiset<int, greater>>(false, mSet);return pair<bool, multiset<int, greater>>(true, mSet);}void TestFindMinKNums3(){int a[] = { 4, 5, 1, 6, 2, 7, 3, 8 };pair<bool,multiset<int, greater>> ret = FindMinKNums3(a,sizeof(a) / sizeof(a[0]), 4);if (ret.first){multiset<int, greater>::iterator it = ret.second.begin();while (it != ret.second.end()){cout << *it << " ";++it;}cout << endl;}else{cout << "数组有误!" << endl;}}


1 0
原创粉丝点击