zoukankan      html  css  js  c++  java
  • 算法设计分析——分治策略选取第k大元素

    1.问题

    通过分治策略,选取第k小元素。

    2.解析

    通过快速排序和分治的思想,每次随机选取主元,判断小于主元的元素的个数,如果个数大于k则递归寻找左半段,如果个数小于k则递归寻找右半段

    3.设计

     1 int find_kth(int l, int r, int k) {
     2 
     3     if (l == r)return a[l];//递归边界
     4 
     5     int temp = a[random(l, r)];//随机选取主元
     6 
     7     int cnt = 0;//计比主元大的个数
     8 
     9     int i = l, j = r;
    10 
    11     while (i <= j) {
    12 
    13         while (a[i] > temp&& i <= j)i++, cnt++;
    14 
    15         while (a[j] <= temp && i <= j)j--;
    16 
    17         if (i < j) {
    18 
    19             swap(a[i], a[j]);
    20 
    21             cnt++;
    22 
    23         }
    24 
    25         i++, j--;
    26 
    27     }
    28 
    29     if (cnt >= k) {//若k<=cnt,就在左半段中递归寻找第k大
    30 
    31         return find_kth(l, l + cnt - 1, k);
    32 
    33     }
    34 
    35     else {//否则在就在右半段中递归寻找第k-cnt大的数
    36 
    37         return find_kth(l + cnt, r, k - cnt);
    38 
    39     }
    40 
    41

    4.分析

    时间复杂度:O(nlogn)

    空间复杂度:O(n)

    5.源码

    https://github.com/BambooCertain/Algorithm.git

     1 #include<stdio.h>
     2 #include<algorithm>
     3 #include<iostream>
     4 using namespace std;
     5 int a[100010];
     6 void swap(int& x, int& y) {
     7     int temp = x;
     8     x = y;
     9     y = temp;
    10 }
    11 int random(int l, int r) {//返回一个在[l,r]范围内的随机整数
    12     return rand() % (r - l + 1) + l;
    13 }
    14 int find_kth(int l, int r, int k) {
    15     if (l == r)return a[l];//递归边界
    16     int temp = a[random(l, r)];//随机选取主元
    17     int cnt = 0;//计比主元大的个数
    18     int i = l, j = r;
    19     while (i <= j) {
    20         while (a[i] > temp&& i <= j)i++, cnt++;
    21         while (a[j] <= temp && i <= j)j--;
    22         if (i < j) {
    23             swap(a[i], a[j]);
    24             cnt++;
    25         }
    26         i++, j--;
    27     }
    28     if (cnt >= k) {//若k<=cnt,就在左半段中递归寻找第k大
    29         return find_kth(l, l + cnt - 1, k);
    30     }
    31     else {//否则在就在右半段中递归寻找第k-cnt大的数
    32         return find_kth(l + cnt, r, k - cnt);
    33     }
    34 }
    35 int main() {
    36     int n; cin >> n;
    37     for (int i = 1; i <= n; i++)cin >> a[i];
    38     int k; cin >> k;
    39     cout << find_kth(1, n, k) << endl;
    40 }
    完整代码
  • 相关阅读:
    c3p0连接池c3p0-config.xml配置文件各属性的意义
    MVC案例-架构分析
    jsp中文乱码
    JSP标签
    JSP_include指令
    JavaWeb_请求转发
    JavaWeb_域对象的属性操作
    JavaWeb_JSP语法
    345. Reverse Vowels of a String
    541. Reverse String II
  • 原文地址:https://www.cnblogs.com/DreamACMer/p/12650623.html
Copyright © 2011-2022 走看看