LeetCode164——最大間距
阿新 • • 發佈:2019-01-13
我的LeetCode程式碼倉:https://github.com/617076674/LeetCode
原題連結:https://leetcode-cn.com/problems/maximum-gap/description/
題目描述:
知識點:桶排序
思路:桶排序
如果陣列中的元素個數小於2,直接返回0即可。
對於n(n >= 2)個元素,假設其中的最大值是max,最小值是min。
如果max和min相等,顯然我們應該返回0。
否則,為其準備n + 1個桶,每個桶中的數字區間儘量平均分配,即第一個桶中存放[min, min + capacity)區間內的數字,最後一個桶中存放[max - capacity, max]區間內的數字。顯然,max和min已經保證了第一個桶和最後一個桶不是空桶。
顯然,將n個元素放進n + 1個桶裡,至少會有一個空桶。同一個桶內的差值必然小於capacity,而間隔一個空桶的差值必然會大於capacity。因此,最大差值只可能在空桶的兩邊產生,即空桶的後一個非空桶的最小值減去空桶的前一個非空桶的最大值。
由此計算方式,我們也可以發現,我們無需儲存桶中的所有元素,只需儲存桶中的最大值和最小值即可,即陣列maxBuckets和minBuckets,其初始化均為-1,表示為空桶。
如何一次遍歷maxBuckets和minBuckets陣列來求出最大差值呢?
我們需要用一個pre指標儲存前一個非空桶的最大值,由於min一定在第一個桶,所以第一個桶一定非空,這為我們的計算帶來了方便。一旦遇到非空桶,我們就更新結果result和pre指標的值即可。
時間複雜度和空間複雜度均是O(n),其中n為陣列中的元素個數。
JAVA程式碼:
public class Solution { public int maximumGap(int[] nums) { if (nums.length < 2) { return 0; } int max = Integer.MIN_VALUE; int min = Integer.MAX_VALUE; for (int i = 0; i < nums.length; i++) { if (nums[i] > max) { max = nums[i]; } if (nums[i] < min) { min = nums[i]; } } if(min == max){ return 0; } int[] maxBuckets = new int[nums.length + 1]; Arrays.fill(maxBuckets, -1); int[] minBuckets = new int[nums.length + 1]; Arrays.fill(minBuckets, -1); int capacity = (int) Math.ceil((double) (max - min) / (nums.length + 1)); for (int i = 0; i < nums.length; i++) { int index = (nums[i] - min) / capacity; if (nums[i] == max) { //最大值放進最後一個桶裡 index = nums.length; } if (maxBuckets[index] == -1) { maxBuckets[index] = nums[i]; } else if (nums[i] > maxBuckets[index]) { maxBuckets[index] = nums[i]; } if (minBuckets[index] == -1) { minBuckets[index] = nums[i]; } else if (nums[i] < minBuckets[index]) { minBuckets[index] = nums[i]; } } int result = 0; int pre = maxBuckets[0]; //第一個桶有min,一定不是空桶 for (int i = 1; i < maxBuckets.length; i++) { if (maxBuckets[i] != -1) { result = Math.max(result, minBuckets[i] - pre); pre = maxBuckets[i]; } } return result; } }
LeetCode解題報告: