1. 程式人生 > >從無序序列中求這個序列排序後鄰點間最大差值的O(n)算法

從無序序列中求這個序列排序後鄰點間最大差值的O(n)算法

算法 之間 一個 差值 最小 size 復雜度 play 實現

標題可能比較繞口,簡單點說就是給你一個無序數列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\n",ans); 37 return 0; 38 }
View Code

從無序序列中求這個序列排序後鄰點間最大差值的O(n)算法