【洛谷】P1138 第k小整数

题目地址:

https://www.luogu.com.cn/problem/P1138

题目描述:
现有 n n n个正整数,要求出这 n n n个正整数中的第 k k k个最小整数(相同大小的整数只计算一次)。

输入格式:
第一行为 n n n k k k;第二行开始为 n n n个正整数的值,整数间用空格隔开。

输出格式:
k k k个最小整数的值;若无解,则输出NO RESULT

数据范围:
n ≤ 10000 n \leq 10000 n10000 k ≤ 1000 k \leq 1000 k1000,正整数均小于 30000 30000 30000

先用哈希表相同数字只保留一个,接着用快速选择算法。代码如下:

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

const int N = 1e4 + 10;
int n, k, a[N], idx;
unordered_set<int> st;

int quick_select(int l, int r) {
  if (l >= r) return a[l];
  int i = l, j = r, piv = a[l + (r - l >> 1)];
  while (i <= j) {
    while (a[i] < piv) i++;
    while (a[j] > piv) j--;
    if (i <= j) {
      swap(a[i], a[j]);
      i++;
      j--;
    }
  }

  if (k <= j) return quick_select(l, j);
  else if (k >= i) return quick_select(i, r);
  else return a[k];
}

int main() {
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; i++) {
    int x;
    scanf("%d", &x);
    if (!st.count(x)) {
      st.insert(x);
      a[++idx] = x;
    }
  }
  
  if (k < 1 || k > idx) puts("NO RESULT");
  else printf("%d\n", quick_select(1, idx));
}

时空复杂度 O ( n ) O(n) O(n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值