• 从无序序列中求这个序列排序后邻点间最大差值的O(n)算法


    标题可能比较绕口,简单点说就是给你一个无序数列A={a1,a2,a3……an},如果你把这个序列排序后变成序列B,求序列B中相邻两个元素之间相差数值的最大值。

    注意:序列A的元素的大小在[1,2^31-1]之间

    首先,因为要O(n)查找,你不能对序列A进行排序。

    不过我们有显而易见的一个结论那就是最大差值,肯定大于平均差值

    而序列的平均差值avg=(MAX(ai)-MIN(ai))/n-1

    这个结论有啥用呢?

    答:可以用来分块,我以avg为块长把n个元素用映射函数f(x)=(x-MIN(a[i]))/avg  映射到n-1个块内。

    首先块内的差值的肯定小于平均值,所以就不用算了,所以只要算块间的差值,而块间的差值就是一个块的最大值,减去另一个块的最小值

    上述算法都可以O(n)实现,所以总算法复杂度O(n)。(*^▽^*)

    代码实现:

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <vector>
     5 using namespace std;
     6 const int SIZE = 1e6+7;
     7 int a[SIZE];
     8 int maxVal[SIZE],minVal[SIZE];
     9 
    10 int main(){
    11     int n,MIN = 2100000000+7,MAX = -1;
    12     scanf("%d",&n);
    13     for(int i=0;i<n;++i){
    14         scanf("%d",&a[i]);
    15         MIN = min(MIN,a[i]);
    16         MAX = max(MAX,a[i]);
    17         maxVal[i] = -1;
    18         minVal[i] = 2100000000 + 7;
    19     }
    20     int temp = (MAX-MIN)/(n-1);
    21     for(int i=0;i<n;++i){
    22         int id = (a[i] - MIN)/temp;
    23         minVal[id] = min(minVal[id],a[i]);
    24         maxVal[id] = max(maxVal[id],a[i]);
    25     }
    26     int ans = (MAX-MIN)/(n-1);
    27     MAX = -1,MIN = -1;
    28     for(int i=0;i<=n;++i){
    29         if(maxVal[i] == -1) continue;
    30         MIN = minVal[i];
    31         if(MAX != -1){
    32             ans = max(ans,MIN-MAX);
    33         }
    34         MAX = maxVal[i];
    35     }
    36     printf("%d
    ",ans);
    37     return 0;
    38 }
    View Code
  • 相关阅读:
    (4) 编译 Android-5.0 源码
    (3) 下载 Android-5.0 源码
    (2) 搭建 Android 系统开发环境
    npm 安装 --save-dev 与 --save的使用与区别
    一点目标
    AcWing 875. 快速幂
    Codeforces Round #604 (Div. 2)
    2019年安徽大学ACM/ICPC实验室新生赛(公开赛)D 不定方程
    C语言黑与白问题
    AcWing 92. 递归实现指数型枚举
  • 原文地址:https://www.cnblogs.com/qswg/p/8687132.html
Copyright © 2020-2023  润新知