在O(n)时间内找到数组中任意第K小的数

来源:互联网 发布:golang defer 函数 编辑:程序博客网 时间:2024/05/16 15:44
// 29 FindKthNum.cpp : Defines the entry point for the console application.///*******************************************************************************************************剑指offer面试题29  P180* 题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如:输入一个长度为9的数组{1,2,3,2,* 2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.* 分析:*          方案1:最直观的想法,即先对数组进行排序,找出每个数字出现的次数。但是排序的时间复杂度是O(nlogn).   方案2:数组中有一个数字超过了数组长度的一。如果把这个数组排序,那么排序之后位于数组中间的数字一定   就是那个出现次数超过一半的数字。因此本题等价于寻找数组的中位数,即第n/2小的数。受快速排序的启发,   我们可以在O(n)的时间内找出数组中任意第k小的数。*********************************************************************************************************/#include "stdafx.h"#include <iostream>using namespace std;void Exchange(int& a, int& b);int Partition(int* a, const int& first, const int& last);void QuickSort(int* a, const int& first, const int& last);int FindKthNum(int* a, const int& first, const int& last, const int& k);int _tmain(int argc, _TCHAR* argv[]){int a[9] = {1,2,3,2,2,2,5,4,2};int k = 0;int Len = sizeof(a)/sizeof(int);//QuickSort(a, 0, Len-1, Len);k = FindKthNum(a, 0, Len-1, Len-2);cout<<"The Kth Min Num is: "<<k<<endl;for(;;);return 0;}/****************************************************************************************************** Author:sky* Functiuon:QuickSort           * Description:对元素进行快速排序        * Access Level:NULL* Input:                       a:    待排序数组        first:数组起点(从0开始)        last: 数组终点* Output:        NULL        * Return:        NULL       *****************************************************************************************************/int FindKthNum(int* a, const int& first, const int& last, const int& k){int q = 0;if(NULL == a)return -1;// 寻找第k小的数q = Partition(a, first, last);while(k != q){if(q > k){q = Partition(a, first, q-1);}else{q = Partition(a, q+1, last);}}return a[k];}/****************************************************************************************************** Author:sky* Functiuon:QuickSort           * Description:对元素进行快速排序        * Access Level:NULL* Input:        a:    待排序数组        first:数组起点(从0开始)        last: 数组终点* Output:        NULL        * Return:        NULL       *****************************************************************************************************/void QuickSort(int* a, const int& first, const int& last){int q = 0;if(first < last){q = Partition(a, first, last);QuickSort(a, first, q-1);QuickSort(a, q+1, last);}}/****************************************************************************************************** Author:sky* Functiuon:Partition           * Description:划分函数,选取一个主元(关键字),函数执行完成后,该主元左边的数字均小于该主元主元右边的数字均大于等于该主元,主元位于排序后的数组的最终位置上。        * Access Level:NULL* Input:a:    待划分数组first:数组划分起点(从0开始)last: 数组划分终点* Output:NULL        * Return:主元位置(从0开始)       *****************************************************************************************************/int Partition(int* a, const int& first, const int& last){int i = -1;//哨兵int j = 0;//遍历索引int Key = a[last];        //主元for(j=0; j!=last; j++){if(a[j] <= Key){i++;Exchange(a[j], a[i]);}}i++;Exchange(a[last],a[i]);return i;}/****************************************************************************************************** Author:sky* Functiuon:Exchange          * Description:交换两个整形元素a和b的值     * Access Level:NULL* Input:        a:    待交换元素1        b:    待交换元素2* Output:NULL        * Return:NULL       *****************************************************************************************************/void Exchange(int& a, int& b){int temp = 0;temp = a;a = b;b = temp;}

0 0
原创粉丝点击