随手练——O(n)解决无序数组排序后的相邻最大差值

题目从这儿看到的 : https://mp.weixin.qq.com/s/2OXg67MfBuQjDPAJxxD8rQ,但是公众号上讲错了,问题还挺严重的。


 题目知识点:桶排序。

题目:有一个无序数组2,3,1,4,6,排序后是1,2,3,4,6,最大差值是 6 - 4 = 2。

  1. 先找到数组的max和min。
  2. 创建一个长度为N+1的桶,前N个桶,(max-min)/N得到范围,左闭右开,最后一个桶只存储最大值。
  3. 除去第一个和最后一个,也就是N-1个数往N个桶里放,那么至少会有一个桶为空。(鸽笼原理)
  4. 遍历新数组Array,计算每一个非空桶中的最大值,与下一个非空桶的最小值的差,数值最大的差即为原数组排序后的相邻最大差值。(所以,每个桶只需要记录当前桶的最大值、最小值即可)

  原公众号文章就是第四步错了:

举个简单的例子就知道是不对的了,最大值并不一定出现 在空桶的两侧。

一定会有一个空桶,只能告诉我们:最大差值一定不再同一个桶里。但并不一定在空桶两侧。

代码实现:

#include "tools.h"

int find_Max_Offset(int *a, int length) {
    int min = getMin(a, length), max = getMax(a, length);
    if (max == min) return 0;
    bool *exsit = new bool[length + 1];
    memset(exsit, false, sizeof(bool)*(length + 1));
    int *MAX = new int[length + 1];
    int *MIN = new int[length + 1];

    for (int i = 0; i < length; i++) {
        int index = (a[i] - min) * length / (max - min);
        if (!exsit[index]) {
            MAX[index] = MIN[index] = a[i];
            exsit[index] = true;
        }
        else {
            MAX[index] = a[i] > MAX[index] ? a[i] : MAX[index];
            MIN[index] = a[i] < MIN[index] ? a[i] : MIN[index];
        }
    }

    int offset = 0;
    for (int i = 0; i < length;) {
        int max = MAX[i++];
        while (exsit[i] == false) i++;
        int min = MIN[i];
        offset = min - max > offset ? min - max : offset;
    }
    return offset;
}

 

posted @ 2019-01-31 21:20  czc1999  阅读(93)  评论(0编辑  收藏  举报