求最小的k个数

发布时间:2020-07-01 13:11:38 作者:Sekai_Z
来源:网络 阅读:488

输入n个整数,找出其中最小的k个数

    解法1:需要修改输入的数组,基于partition快速排序来做,时间复杂福O(N)

    分析:基于数组的第k个元素来调整,使的比第k个数大的所有数字放到数组的右边,这样,数组左边k个就是最小的k个数字

void GetLestNumber(int *input, int n, int *output, int k)
{
	if (input == NULL || output == NULL || k > n || n <= 0 || k <= 0)
		return;

	int start = 0;
	int end = n - 1;
	int index = Partition(input, n, start, end);
	while (index != k - 1)
	{
		if (index > k - 1)
		{
			end = index - 1;
			index = Partition(input, n, start, end);
		}
		else
		{
			start = index + 1;
			index = Partition(input, n, start, end);
		}
	}
	for (int i = 0; i < k; ++i)
	{
		output[i] = input[i];
	}
}

解法二:

    分析:先创建一个大小为k的数据容器来存储最小的k个数字,接着每次从输入的n个整数中读入一个数,如果容器中少于k个数则直接放,若大于则表示容器以满,此时找出容器中最大值,然后拿输入的值和最大值比较,若待插入的数小于最大值,则直接替换。

    最大堆的结构每次可以在O(1)得到最大值,但需要o(logk)时间来完成删除及插入

    红黑树同上,但是代码简于大堆

void GetLestNumber(int *input, int n, int *output, int k)
{
        if (input == NULL || output == NULL || k > n || n <= 0 || k <= 0)
          return;

 int start = 0;
      int end = n - 1;
    int index = Partition(input, n, start, end);
        while (index != k - 1)
      {
           if (index > k - 1)
               {
                   end = index - 1;
                    index = Partition(input, n, start, end);
            }
           else
                {
                   start = index + 1;
                  index = Partition(input, n, start, end);
            }
   }
   for (int i = 0; i < k; ++i)
      {
           output[i] = input[i];
       }
}
解法二:
    分析:先创建一个大小为k的数据容器来存储最小的k个数字,接着每次从输入的n个整数中读入一个数,如果容器中少于k个数则直接放,若大于则表示容器以满,此时找出容器中最大值,然后拿输入的值和最大值比较,若待插入的数小于最大值,则直接替换。
    最大堆的结构每次可以在O(1)得到最大值,但需要o(logk)时间来完成删除及插入
const int N = 1000;
const int k = 10;
void AdjustDown(int *a, int size, int parent)
{
 int child = (parent - 1) / 2;
       while (child < size)
     {
           if (child+1<size&&a[child]>a[child + 1])
                      child++;
            if (a[child]>a[parent])
          {
                   swap(a[child], a[parent]);
                  parent = child;
                     child = (parent - 1) / 2;
           }
           else
                        break;
      }
}
void GetTopK(int*a)
{
  assert(k < N);
   int top[k];
 for (int i = 0; i < k; i++)
      {
           top[i] = a[i];
      }
   for (int i = (k - 2) / 2; i >= 0; i++)
   {
           AdjustDown(top, k, i);
      }
   for (int i = N-k-1; i < N; i++)
  {
           if (a[i]>top[0])
         {
                   top[0] = a[i];
                      AdjustDown(top, k, 0);
              }
   }
}


推荐阅读:
  1. 剑指offer:最小的k个数
  2. 求珠子的长度最小区间

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

offer 剑指

上一篇:计算机基础知识+学习方向

下一篇:C#从SQL server数据库中读取l图片和存入图片

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》