選擇問題——選取第K小元素

鴨脖發表於2012-12-16

今天看到騰訊的一道面試題目,感覺都考的特別基礎,但是自己有時候真的是學的不好,所以現在記下來:

查詢最小的k個元素

題目:輸入n個整數,輸出其中最小的k個。

例如輸入1,2,3,4,5,6,7,8這8個數字,則最小的4個數字為1,2,3,4


這道題目其實就是書上的k小選擇問題,在講述排序演算法的時候其實已經都講過了,只不過當時是輸出一個但是現在是輸出k個,都一樣啊,你找出第k個元素之後,把它左邊的直接輸出就好了,因為陣列已經partition好了。所以這道題目還是k小選擇問題,你看,面試題其實都是書上最基本的題目。


下面是我寫的,和書上的不太一樣,但是結果是一樣的,思想也是一樣的。

==================================================================

#include<iostream>
#include<string>
#include<stdlib.h>
using namespace std;


void swap(int* a,int i,int j){//exchange the items in the array
int tem = a[i];
a[i] = a[j];
a[j] = tem;
}


//print a particular array
void printArray(int* a,int n){
for(int i=0;i<n;i++){
cout<<a[i]<<" ";
}
cout<<endl;
}


int Partition(int* a,int left,int right){//partition the array from left to right according to the item on the left
int i = left + 1;
int j = right;
do{
while(a[i]<=a[left]) i++;//左邊是小於等於,右邊是大於
while(a[j] > a[left]) j--;
if(i<j)
swap(a,i,j);
}while(i<j);
//swap(a,left,i);
return j;
}


//select the Kth min element
int selectKMin(int* a,int k,int n){
int left = 0,right = n-1;
do
{
int j = rand()%(right - left + 1)+left;//randomly select the main item
swap(a,left,j);
int i = Partition(a,left,right);
if(i == k-1)
return i;
else if(i < k-1)
left = i;
else
right = i;
}
while(true);
}


int main(){
int a[13] = {2,4,3,1,5,7,23,9,10,33,55,0,23};
int i = selectKMin(a,9,13);
printArray(a,i+1);
}


關鍵還是partition函式。


=============================之後我又改變成了模板:

#include<iostream>
#include<string>
#include<stdlib.h>
using namespace std;


template<typename T>
void swap(T* a,int i,int j){//exchange the items in the array
T tem = a[i];
a[i] = a[j];
a[j] = tem;
}


//print a particular array
template<typename T>
void printArray(T* a,int n){
for(int i=0;i<n;i++){
cout<<a[i]<<" ";
}
cout<<endl;
}


template<typename T>
int Partition(T* a,int left,int right){//partition the array from left to right according to the item on the left
int i = left + 1;
int j = right;
do{
while(a[i]<=a[left]) i++;
while(a[j] > a[left]) j--;
if(i<j)
swap(a,i,j);
}while(i<j);
//swap(a,left,i);
return j;
}


//select the Kth min element
template<typename T>
int selectKMin(T* a,int k,int n){
int left = 0,right = n-1;
do
{
int j = rand()%(right - left + 1)+left;//randomly select the main item
swap(a,left,j);
int i = Partition(a,left,right);
if(i == k-1)
return i;
else if(i < k-1)
left = i;
else
right = i;
}
while(true);
}


int main(){
string a[6] = {"xuyabo","liuxinrui","hahaha","loveyouall","why","but"};
int i = selectKMin(a,3,6);
printArray(a,i+1);
}


相關文章