选择问题——选取第K小元素

本文介绍了一种解决查找最小的K个元素问题的高效算法,并通过实例演示了如何使用快速选择算法找到数组中最小的K个数值。该算法不仅适用于整数数组,还通过模板实现了对不同类型数据的支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天看到腾讯的一道面试题目,感觉都考的特别基础,但是自己有时候真的是学的不好,所以现在记下来:

查找最小的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);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值