【剑指offer】题目1371:最小的K个数

题目描述:

输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

输入:

每个测试案例包括2行:

第一行为2个整数n,k(1<=n,k<=200000),表示数组的长度。

第二行包含n个整数,表示这n个数,数组中的数的范围是[0,1000 000 000]。

输出:

对应每个测试案例,输出最小的k个数,并按从小到大顺序打印。

样例输入:
8 44 5 1 6 2 7 3 8
样例输出:
1 2 3 4
基于快速排序划分的思路,平均时间复杂度O(n)
#include <iostream>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <algorithm>


void swap(int *a, int *b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

int Partition(int data[],int length, int lhs, int rhs)
{
	if (data == NULL || length <= 0 || lhs < 0 || rhs >= length)
	{
		return -1;
	}
	int pivot = data[rhs];
	int small = lhs - 1;
	for (int i = lhs; i < rhs; i++)
	{
		if (data[i] < pivot)
		{
			small++;
			if (small != i)
			{
				swap(&data[i], &data[small]);
			}
		}
	}
	small++;
	swap(&data[small], &data[rhs]);
	return small;
}

void GetleastKnumber(int *data, int n, int k)
{
	if (data == NULL || n <= 0 || k <= 0)
	{
		return;
	}
	if (k >= n)
	{
		std::sort(data, data+n);
		for (int i = 0; i < n; i++)
		{
			if (i > 0)
			{
				printf(" ");
			}
			printf("%d", data[i]);
		}
		printf("\n");
		return ;
	}
	int lhs = 0, rhs = n-1;
	int index = Partition(data, n, lhs, rhs);
	while(k-1 != index)
	{
		if (k-1 < index)
		{
			rhs = index -1;
			index = Partition(data, n, lhs, rhs);
		}
		else{
			lhs = index + 1;
			index = Partition(data, n, lhs, rhs);
		}
	}
	std::sort(data, data+k);
	for (int i = 0; i < k; i++)
	{
		if (i > 0)
		{
			printf(" ");
		}
		printf("%d", data[i]);
	}
	printf("\n");
	return ;
}

int GetKthSmallNum(int *data, int n, int k)
{
	return 0;
}

int main()
{
	
	int n, k;
	while(scanf("%d %d", &n, &k) != EOF)
	{
		int *data = new int[n];
		if (data == NULL)
		{
			break;
		}
		for (int i = 0; i < n; i++)
		{
			scanf("%d", &data[i]);
		}
		GetleastKnumber(data, n, k);
		delete[] data;
	}
	
	//system("pause");
	return 0;
}


 
  
 
  
#include <iostream>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <algorithm>


void swap(int *a, int *b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

int Partition(int data[],int length, int lhs, int rhs)
{
	if (data == NULL || length <= 0 || lhs < 0 || rhs >= length)
	{
		return -1;
	}
	int pivot = data[rhs];
	int small = lhs - 1;
	for (int i = lhs; i < rhs; i++)
	{
		if (data[i] < pivot)
		{
			small++;
			if (small != i)
			{
				swap(&data[i], &data[small]);
			}
		}
	}
	small++;
	swap(&data[small], &data[rhs]);
	return small;
}

void GetleastKnumber(int *data, int n, int k)
{
	if (data == NULL || n <= 0 || k <= 0)
	{
		return;
	}
	if (k >= n)
	{
		std::sort(data, data+n);
		for (int i = 0; i < n; i++)
		{
			if (i > 0)
			{
				printf(" ");
			}
			printf("%d", data[i]);
		}
		printf("\n");
		return ;
	}
	int lhs = 0, rhs = n-1;
	int index = Partition(data, n, lhs, rhs);
	while(k-1 != index)
	{
		if (k-1 < index)
		{
			rhs = index -1;
			index = Partition(data, n, lhs, rhs);
		}
		else{
			lhs = index + 1;
			index = Partition(data, n, lhs, rhs);
		}
	}
	std::sort(data, data+k);
	for (int i = 0; i < k; i++)
	{
		if (i > 0)
		{
			printf(" ");
		}
		printf("%d", data[i]);
	}
	printf("\n");
	return ;
}

int GetKthSmallNum(int *data, int n, int k)// 函数返回第K小的数
{
	if (data == NULL || k > n)
	{
		return -1;
	}
	int lhs = 0, rhs = n-1;
	int index = Partition(data, n, lhs, rhs);
	while(index != k-1)
	{
		if(k-1 < index)
		{
			rhs = index -1;
			index = Partition(data, n, lhs , rhs);
		}
		else{
			lhs = index + 1;
			index = Partition(data, n, lhs , rhs);
		}
	}
	return data[index];
}

int main()
{
	
	int n, k;
	while(scanf("%d %d", &n, &k) != EOF)
	{
		int *data = new int[n];
		if (data == NULL)
		{
			break;
		}
		for (int i = 0; i < n; i++)
		{
			scanf("%d", &data[i]);
		}
		//GetleastKnumber(data, n, k);
		GetKthSmallNum(data, n, k);
		delete[] data;
	}
	
	//system("pause");
	return 0;
}


你可能感兴趣的:(快速排序,九度OJ)