无序数组排序后,求相邻两数之间的最大差值,代码过程详解

题目:

给定一个数组,求排序之后,相邻两数之间的最大差值,要求时间复杂度O(N),且要求不能用非基于比较的排序。

示例:

例如:3  1  6  2  7   排序之后  :  1  2  3  6  7   则相邻最大差值为3(6-3=3)

解法:

1.循环数组,找到最小值和最大值。

2.若有N个数,就创建N+1个桶来装数,分别为   0号桶,1号桶,2号桶......N号桶 。

3.定义三个大小为N+1的数组。

4.循环原数组, 确定每个数被装入哪个桶。如何确定?-->which = (num-min)*N/(max-min),每个桶内只能存放进入该桶的最大值和最小值。

5.循环求后一个桶的最小值减去前一个桶的最大值,即得到最大差值。若是空桶,则跳过。

注释:

1.一共N个数,N+1个桶,且全局最小值放在第一个桶,全局最大值放在最后一个桶,那么中间必有桶是空桶。

2.空桶的意义:排除最大差值的两个相邻的数在同一个桶中。

空桶左边的桶内差值最大是9,空桶两边最小差值为11(30-19=11),但是并不是空桶两边的差值就是最大,看图中最右边两个桶,他们的差值是19(49-30=19)。因此,空桶的意义在于排除最大差值是在同一个桶中出现。

 代码实现:

# 空桶的意义是说明:最大差值不可能是来自同一个桶内的两个数。
import sys
def max_difference(arr):
    max_num = -sys.maxsize  # 最大值取系统最小值
    min_num = sys.maxsize  # 最小值取系统最大值
    for i in arr:  # 循环arr数组中的每一个数
         max_num = max_num if i < max_num else i
         min_num = min_num if i > min_num else i
    bool_bucket = ["false"] * (len(arr)+1)
    min_bucket = [None] * (len(arr)+1)
    max_bucket = [None] * (len(arr)+1)
    for i in arr:
        which = which_bucket(i, min_num, max_num, len(arr))
        if bool_bucket[which] == "false":
            min_bucket[which] = i
            max_bucket[which] = i
            bool_bucket[which] = "true"
        else:
            min_bucket[which] = min(min_bucket[which], i)
            max_bucket[which] = max(min_bucket[which], i)

    pre_max = max_bucket[0]
    ret = 0
    for i in range(1, len(arr)+1):  # 从第二个桶开始
        if bool_bucket[i] == "true":  # 假设空桶就跳过,利用空桶下一个桶中最小值减去空桶上一个桶的最大值求差值。
           ret = max(ret, (min_bucket[i] - pre_max))
           pre_max = max_bucket[i]
    return ret

# 求数组中的数分配的桶号
def which_bucket(num, min_num, max_num, len):
    return int((num-min_num) * len / (max_num - min_num))


arr = [4, 3, 2, 1, 7]
print(max_difference(arr))
# 3  --> 7-4=3

猜你喜欢

转载自blog.csdn.net/m0_38109046/article/details/88089917