zoukankan      html  css  js  c++  java
  • 无序数组求第K大/第K小的数

    方法一:quicksort

    根据快排思想,从后往前找比基准数小的,交换位置。

    从前往后找比基准数大的,交换位置。

    最后安放基准数。

    保证 l到p 是大数,若 p-l+1==k 那么p就是第K大

    若 p-l+1<k 那么从 p+1 到 r 中 找 k-(p-l+1)大的数

    若 p-l+1>k 那么从 l 到 p-1中 找第k大的数。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<string>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<algorithm>
     7 using namespace std;
     8 int n, k;
     9 int a[100010];
    10 int par(int l, int r)
    11 {
    12     int t = a[l];
    13     while (l < r)
    14     {
    15         while (l < r &&a[r] <= t)    r--;
    16         a[l] = a[r];
    17         while (l < r &&a[l] >= t)    l++;
    18         a[r] = a[l];
    19     }
    20     a[l] = t;
    21     return l;
    22 }
    23 int search(int l, int r,int k)
    24 {
    25     if (l <= r)
    26     {
    27         int p = par(l, r);
    28         if (p - l + 1 == k)    return p;
    29         else if (p - l + 1 < k)    return search(p+1,r,k-(p-l+1));
    30         else return search(l,p-1,k);
    31     }
    32 }
    33 int main()
    34 {
    35     cin >> n >> k;
    36     for (int i = 1; i <= n; i++)
    37         cin >> a[i];
    38     cout << a[search(1, n, k)] << endl;
    39 
    40     return 0;
    41 }
    View Code

    方法二:最小堆

    原本用swap函数的,后来好像swap并不能使两个数交换,以后我一定自己写。(鞠躬表示歉意)

    搞了半天搞错了,还是挖坑吧。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<string>
     4 #include<cstring>
     5 #include<map>
     6 #include<algorithm>
     7 #include<cmath>
     8 using namespace std; 
     9 int n, a[11000],b,k;
    10 void adjust(int i,int n)
    11 {
    12     int child = 2 * i;
    13     while (child <= n)
    14     {
    15         if (child + 1 <= n && a[child] < a[child + 1])
    16             child++;
    17         if (a[child] < a[i])
    18             break;
    19         int t = a[child];
    20         a[child] = a[i];
    21         a[i] = t;
    22         i = child;
    23         child = 2 * i;
    24     }
    25 }
    26 void dui(int n)
    27 {
    28     for (int i = n / 2; i >= 1; i--)
    29         adjust(i, n);
    30 }
    31 int main()
    32 {
    33     cin >> n >> k;
    34     for (int i = 1; i <= k; i++)
    35         cin >> a[i];
    36     dui(k);
    37     for (int i = 1; i <= n - k; i++)
    38     {
    39         cin >> b;
    40         if (b < a[1])
    41         {
    42             a[1] = b;
    43             adjust(1,k);
    44         }
    45     }
    46     cout << a[1] << endl;
    47     return 0;
    48 }
    View Code
    No matter how you feel, get up , dress up , show up ,and never give up.
  • 相关阅读:
    欧拉回路和欧拉路径
    nth_element函数
    Java读写Excel
    如何指定tomcat中session过期时间
    Java 正则表达式
    Java与模式阅读笔记(1)依赖倒转原则
    Linux vi 命令详解
    native2ascii & ascii2native
    Linux 下zip包的压缩与解压
    linux设置邮件自动转发
  • 原文地址:https://www.cnblogs.com/Kaike/p/9931294.html
Copyright © 2011-2022 走看看