题目描述
给定一个数组,求如果排序之后,相邻两数的最大差值,要求时 间复杂度O(N),且要求不能用非基于比较的排序
思路
思路:桶排序
- 假设数组长度为n,准备n+1个桶
- 遍历该数组,将最小值放入到第1个位置,将最大值放入到最后一个位置
- 将剩下的数等分成等分成n-1份依次放入剩下对应范围的桶中,
- 最后这n+1个桶中至少有一个空桶,说明桶内的数值差不是最大差值,我们去桶间找最大差值
- 对于每个桶,我们都保存了每个桶的最小值和最大值,从第2个桶开始,每次计算当前桶的最小值与前一个桶(要有元素)的最大值的差,过程中我们动态更新最大差值
具体编码
实现代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| func GetMaxDiff(nums []int) int { maxNum := make([]int, len(nums)+1) minNum := make([]int, len(nums)+1) hasNum := make([]bool, len(nums)+1) min, max := math.MaxInt64, math.MinInt64 maxDiff := math.MinInt64
for _, v := range nums { if v > max { max = v } if min > v { min = v } }
hasNum[0], hasNum[len(nums)] = true, true diff := float64(max-min) / float64(len(nums)-1) for _, v := range nums { indexBucket := int(math.Ceil(float64(v-min) / diff)) if !hasNum[indexBucket] { maxNum[indexBucket] = v minNum[indexBucket] = v } else { if maxNum[indexBucket] < v { maxNum[indexBucket] = v } if minNum[indexBucket] > v { minNum[indexBucket] = v } } hasNum[indexBucket] = true }
lastMax := min for i := 1; i < len(nums); i++ { if hasNum[i] { if maxDiff < minNum[i]-lastMax { maxDiff = minNum[i] - lastMax } lastMax = maxNum[i] }
} return maxDiff }
func main() { nums := utils.RandArrayRange(10, 10, 99) fmt.Println(nums) fmt.Println(GetMaxDiff(nums)) }
|