• 算法导论9.37


    【转】

    题目:

    给出一个O(n)时间的算法,在给定一个有n个不同数字的集合S以及一个正整数k<=n后,它能确定出S中最接近其中位数的k个数。

    ——————————

    算法思想:
    1.找到数组a中第n/2小的数median;
    2.对a中非median数进行|a[i] - median|,得到一个大小为n - 1的数组distance;
    3.寻找distance中第k小的数值;
    4.对distance进行一次遍历,找到小于等于k的数,从而对应得到数组a中的k个数。

    上述每一步的时间复杂度都为O(n),因而最后总的时间复杂度为O(n).

    #include <iostream>
    #include
    <time.h>
    using namespace std;
    //随机化分割
    int randomized_partition(int* a, int p, int r);
    int randomized_select(int* a, int p, int r, int i);
    int main()
    {
    const int LEN = 12;
    int arr[LEN] = { 5, 7, 10, 3, 6, 2, 8, 9, 4, 1, 11 , 12};
    int median = randomized_select(arr, 0, LEN - 1, (LEN - 1)/2);
    int distance[LEN - 1];
    int distance_cpy[LEN - 1];

    int temp = 0;
    int middle;
    for(int i = 0; i < LEN; i++)
    {
    if(arr[i] != median)
    distance[temp
    ++] = abs(arr[i] - median);
    else
    middle
    = i;
    }
    for(int i = 0; i < LEN - 1; i++)
    distance_cpy[i]
    = distance[i];
    int k;
    while(true)
    {
    cout
    <<"输入k:"<<endl;
    cin
    >>k;
    cout
    <<"k邻近值为:"<<endl;
    int kth_value = randomized_select(distance_cpy, 0, LEN - 2, k - 1);
    int* k_arr = new int[k];
    int j = 0;
    //这里要注意,比如中间值为6,那么k = 3,有5,7明显符合要求,他们最近,4,8也符合要求,那么在这选择谁
    if(k%2)
    {
    bool flag = true;
    for(int i = 0; i < LEN - 1; i++)
    {
    if(distance[i] < kth_value)
    {
    if(i < middle)
    k_arr[j
    ++] = median - distance[i];
    else
    k_arr[j
    ++] = median + distance[i];
    }
    else if(distance[i] == kth_value && flag)
    {
    if(i < middle)
    k_arr[j
    ++] = median - distance[i];
    else
    k_arr[j
    ++] = median + distance[i];
    flag
    = false;
    }
    }
    }
    else
    {
    for(int i = 0; i < LEN - 1; i++)
    {
    if(distance[i] <= kth_value)
    {
    if(i < middle)
    k_arr[j
    ++] = median - distance[i];
    else
    k_arr[j
    ++] = median + distance[i];
    }
    }
    }
    for(int i = 0; i < k; i++)
    cout
    <<k_arr[i]<<"\t";
    cout
    <<endl;
    delete[] k_arr;
    }
    }
    //下标为[p, r]之间的元素
    int randomized_partition(int* a, int p, int r)
    {
    srand(time(NULL));
    int q = rand()%(r - p + 1) + p;
    int temp = a[q];
    a[q]
    = a[r];
    a[r]
    = temp;
    int j = p;
    for(int i = p; i < r; i++)
    {
    if(a[i] < a[r])
    {
    if(i != j)
    {
    int temp2 = a[i];
    a[i]
    = a[j];
    a[j]
    = temp2;
    }
    j
    ++;
    }
    }

    temp
    = a[j];
    a[j]
    = a[r];
    a[r]
    = temp;
    return j;
    }
    //迭代版本
    int randomized_select(int* a, int p, int r, int i)
    {
    int q = randomized_partition(a, p, r);
    while(p != r)
    {
    if(i == q)
    return a[q];
    else if(i < q)
    {
    r
    = q - 1;
    q
    = randomized_partition(a, p, r);
    }
    else
    {
    p
    = q + 1;
    q
    = randomized_partition(a, p, r);
    }
    }
    return a[p];
    }
  • 相关阅读:
    (九)springmvc+mybatis+dubbo+zookeeper分布式架构 整合
    (八)springmvc+mybatis+dubbo+zookeeper分布式架构 整合
    (七)springmvc+mybatis+dubbo+zookeeper分布式架构 整合
    (六)springmvc+mybatis+dubbo+zookeeper分布式架构 整合
    28 android资源文件
    1 ArrayList和LinkedList的区别
    27 MediaPlayer和SurfaceView播放视频会闪黑屏一下
    26 事件分发
    25 Notification通知栏
    24 RadioGroup制作底部按钮
  • 原文地址:https://www.cnblogs.com/longdouhzt/p/2119393.html
Copyright © 2020-2023  润新知