zoukankan      html  css  js  c++  java
  • 从无序序列中求这个序列排序后邻点间最大差值的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
  • 相关阅读:
    【LOJ #2290】「THUWC 2017」随机二分图(状压DP)
    【LOJ #2136】「ZJOI2015」地震后的幻想乡(状压DP)
    【CSP-S 2019模拟】题解
    异步编程补漏
    Git(七) 查漏补缺
    ES6(二) let const
    ES6(一) 数组
    JS判断对象是否存在
    Git(六)
    Git(五)
  • 原文地址:https://www.cnblogs.com/qswg/p/8687132.html
Copyright © 2011-2022 走看看