难度:困难
题目:
给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。
如果数组元素个数小于 2,则返回 0。
思考:
这个题目够短了吧?但是难度是困难
跟看到长题目不要慌同样重要的事,看到难度是困难也不要慌!
这个看着也不是很难嘛,
就是找出每两个数之间的距离,最大距离!
思路:
①因为数组是乱序的,可以先对数组进行排序
②然后顺序遍历,找出最大的距离
③就这?嗯就这
代码:
public int maximumGap2(int nums[]) { if (nums.length < 2) return 0; Arrays.sort(nums); int max = Integer.MIN_VALUE; for (int i = 1; i if (nums[i] - nums[i-1] > max) max = nums[i] - nums[i-1]; return max;}
又思考:
有没看到上面这个,没有再看看,
线性时间空间诶,也就是O(n)
上面代码用的是Arrays.srot,之前也说过这是几个排序在一起,最好O(n),但是最好是O(n²)。
因此这种方法虽然行,但是有点不讲武德,耗子尾汁。
所以换个方法,用桶排序,桶排序就不唠嗑了
。。。
还是唠嗑一下吧
一句话总结:划分多个范围相同的区间,每个子区间自排序,最后合并
↓
代码:
public int maximumGap3(int[] nums) { // 小于2直接返回0 if(nums.length < 2) return 0; int n = nums.length; // 获取最大最小值 int max = -1, min = Integer.MAX_VALUE; for (int num : nums) { max = Math.max(num, max); min = Math.min(num, min); } // 最大最小相同直接返回 if(max - min == 0) return 0; // 用于存放每个桶的最大最小值 int[] bucketMin = new int[n-1]; int[] bucketMax = new int[n-1]; Arrays.fill(bucketMax, -1); Arrays.fill(bucketMin, Integer.MAX_VALUE); // 确定桶的间距 int interval = (int) Math.ceil((double)(max - min) / (n - 1)); for (int num : nums) { // 找到每一个值所对应桶的索引 int index = (num - min) / interval; if (num == min || num == max) continue; bucketMax[index] = Math.max(bucketMax[index], num); bucketMin[index] = Math.min(bucketMin[index], num); } // maxGap 表示桶之间最大的差距 int maxGap = 0; // preMax 表示前一个桶的最大值 int previousMax = min; for(int i = 0; i < n - 1; i++) { // 表示某一个桶为空 // 但凡某一个桶不为空,都会在前面的数据中更新掉bucketMax的值 if(bucketMax[i] == -1) continue; maxGap = Math.max(bucketMin[i] - previousMax, maxGap); previousMax = bucketMax[i]; } maxGap = Math.max(maxGap, max - previousMax); return maxGap;}
复杂度分析
时间复杂度:O(N),其中 N 是数组的长度。注意到桶的数量为(max-min)/d≈N-1,也就是O(n)
空间复杂度:O(N),其中 N 是数组的长度。我们开辟的空间大小取决于桶的数量。
--------------------------------------完------------------------------
讲旧时就食shi啦
最紧要睇边个够实力