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
  • 相关阅读:
    读书笔记·如何高效读懂一本书
    读书笔记·微习惯
    LittleTools之输出RenderTexture工具
    常用自制脚本(一):透明度统一修改
    LittleTool之批量修改材质
    曲面Shader
    温故而知新之镜头旋转
    LittleTools之网格输出为模型
    Unity给力插件之ShaderForge(三)
    vue的学习
  • 原文地址:https://www.cnblogs.com/qswg/p/8687132.html
Copyright © 2011-2022 走看看