5. 微软面试题: 查寻最小的k个元素(数组)

5. 微软面试题: 查找最小的k个元素(数组)
题目:输入n个整数,输出其中最小的k个。

例如输入7,2,4,5,1,3,6,88个数字,则最小的4个数字为1234


下面使用快速排序和分治法的思想,

1)先找选一个元素a遍历一次剩余的其他元素,使得a左边的元素都是小于它的,a右边的元素都是大于它的。

2)再统计a 左边的元素或者包括a 与 k的关系,等于的话,就直接输出,大于,那就在左边里面继续1),小于的话,那就在右边里面继续查找k-左边元素的个数-1个最小的整数。


看实现(写的很烂,今儿一点感觉都没有,以后再修正!)

#include <iostream>
#include<vector>
using namespace std;

//使用快速排序的思想,查找最小的k个数
void findmink(int* data, int i, int j, int k, vector<int>& res)
{
	//使用一次快速排序步骤 
	int ii = i+1;
	int jj = j-1;
	int pos = i;
	while(ii <= jj)
	{
		while(ii <= jj && data[jj] > data[pos]) 
			jj --;
		if(ii <= jj)
		{
			int tmp = data[pos];
			data[pos] = data[jj];
			data[jj] = tmp;
			pos = jj;
			jj --;
		}
		while(ii <= jj && data[ii] < data[pos])
			ii ++;
		if(ii <= jj)
		{
			int tmp = data[pos];
			data[pos] = data[ii];
			data[ii] = tmp;
			pos = ii;
			ii --;
		}
	}
	

	if(pos-i+1 == k)
	{//OK
		for(ii=i; ii <= pos; ii++)
			res.push_back(data[ii]);
	}
	else if(pos-i == k)
	{
		for(ii=i; ii < pos; ii++)
			res.push_back(data[ii]);
	}
	else if( pos-i+1 < k)
	{
		for(ii=i; ii <= pos; ii++)
			res.push_back(data[ii]);
		findmink(data, pos +1 , j, k-pos +i -1, res);
	}
	else
	{
		findmink(data, i, pos, k, res);
	}
	 
}

int main()
{
	int array[8] = {7,2,4,5,1,3,6,8};
	vector<int> mink;
	findmink(array, 0, 8, 4, mink);
	int i = 0;
	while(i<mink.size())
	{
		cout << mink[i++] << ",";
	}
	return 0;
}

输出结果为:

1,2,3,4