求解序列第K大数

方法一 hash

//方法一 hash
const int maxn = 10000;
int hashTable[maxn];//计算hash[i]的个数
int main()
{
	int n,k;
	scanf("%d%d", &n,&k);
	fill(hashTable, hashTable + n, 0);
	for (int i = 0; i < n; i++)
	{
		int temp;
		scanf("%d", &temp);
		hashTable[temp]++;
	}
	int sum = 0;
	for (int i = 0; i < maxn; i++)
	{
		sum += hashTable[i];
		if (sum >= k)
		{
			printf("%d", i);
			return 0;
		}
	}
}

方法二 分块

//方法二 分块
const int maxn = 100001;
int count1 = ceil(sqrt(maxn));//块数
int count2 = sqrt(maxn);//每块个数
int block[maxn];//表明第i块中的总个数
int hashTable[maxn];//表示i的个数
int main()
{
	int n, k;
	scanf("%d%d", &n, & k);
	fill(hashTable, hashTable + n, 0);
	fill(block, block + n, 0);
	for (int i = 0; i < n; i++)
	{
		int temp;
		scanf("%d", &temp);
		hashTable[temp]++;
		int id = temp / count2;
		block[id]++;
	}
	int sum = 0;
	for (int i = 0; i < count1; i++)
	{
		if (sum + block[i] >= k)//在第i块中
		{
			int start = i * count2;
			while (true)
			{
				sum += hashTable[start];
				if (sum >= k)
				{
					printf("%d", start);
					return 0;
				}
				start++;
			}
		}
	}
}

方法三 树形数组

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define lowbit(i)(i&(-i))
const int maxn = 10000;
int c[maxn];//表示以i结尾覆盖长度为lowbit(i)的整数(这个整数表示i出现的次数)之和
//5 2
//1 1 4 3 2
//5 3
//1 1 4 3 2
//求解数列第K大
void update(int x, int v)
{
	for (int i = x; i < maxn; i += lowbit(x))
	{
		c[i] += v;
	}
}
int getSum(int x)
{
	int sum = 0;
	for (int i = x; i > 0; i -= lowbit(x))
	{
		sum += c[i];
	}
	return sum;
}
int main()
{
	fill(c, c + maxn, 0);
	int n,k;
	scanf("%d%d", &n,&k);
	
	for (int i = 0; i < n; i++)
	{
		int temp;
		scanf("%d", &temp);
		update(temp, 1);
	}
	int l = 1, r = maxn;
	while (r>l)
	{
		int mid = (r - l) / 2 + l;
		int sum = getSum(mid);
		if (sum >= k)
		{
			r = mid;
		}
		else 
		{
			l = mid+ 1;
		}
	}
	printf("%d", l);
}
posted @ 2021-09-10 21:55  小帆敲代码  阅读(52)  评论(0编辑  收藏  举报