【LeetCode】每日一題164. 最大間距
164. 最大間距
給定一個無序的陣列,找出陣列在排序之後,相鄰元素之間最大的差值。
如果陣列元素個數小於 2,則返回 0。
示例 1:
輸入: [3,6,9,1]
輸出: 3
解釋: 排序後的陣列是 [1,3,6,9], 其中相鄰元素 (3,6) 和 (6,9) 之間都存在最大差值 3。
示例 2:
輸入: [10]
輸出: 0
解釋: 陣列元素個數小於 2,因此返回 0。
說明:
- 你可以假設陣列中所有元素都是非負整數,且數值在 32 位有符號整數範圍內。
- 請嘗試線上性時間複雜度和空間複雜度的條件下解決此問題。
解題思路:
此題難在如何用線性的時間複雜度(O(n))解決,否則直接快排或歸併再取相鄰元素最大差值即可。
此題沒有必要保證元素的絕對有序,使用桶排序保證元素相對有序即可
大體思路:建立若干個桶,每個桶負責固定區間的元素,按照一定規則將元素放進桶中。
-
區間:section = (max - min ) / (n - 1) ,其中 max 為陣列最大值,min 為陣列最小值,n 為陣列長度 。
-
桶的數量: bucketSize = (max - min ) / section + 1。
-
一定規則: idx = (nums[i] - min) / section,idx 為桶的編號。
示例:
假設初始元素為(為了直觀所以排序了):[0,4,5,8,18,19,23,32,39],區間 section = (39 - 0) / (8 - 1) = 5,桶數量 bucketSize = (39 - 0) / 5 + 1 = 8
按照規則將元素放入桶中,如下圖:
再看一種極端情況:等差數列。顯而易見,最大的差值就是 section = 5,
若元素不為等差數列,最大的差值一定大於 section
所以最大的差值不會出現在桶內,因為單個桶內最大的差值小於 section
即最大的差值在桶與桶之間
我們維護每個桶的最大值與最小值,然後遍歷桶,找出之間最大的差值即可。
方法一:桶排序
int n = nums.length;
// 特判
if (n < 2) {
return 0;
}
// 找出最大值,最小值
int max = Arrays.stream(nums).max().getAsInt();
int min = Arrays.stream(nums).min().getAsInt();
// 所有數都相等
if (max - min == 0){
return 0;
}
// 計算桶區間
int section = Math.max(1, (max - min) / (n - 1));
// 桶的個數
int bucketSize = (max - min) / section + 1;
// 每個桶的最小值
int[] min_bucket = new int[bucketSize];
// 每個桶的最大值
int[] max_bucket = new int[bucketSize];
// 初始化桶
Arrays.fill(min_bucket, Integer.MAX_VALUE);
Arrays.fill(max_bucket, -1);
for (int i = 0; i < n; i++) {
// 確定當前值在哪個桶
int idx = (nums[i] - min) / section;
// 更新最大值和最小值
min_bucket[idx] = Math.min(min_bucket[idx], nums[i]);
max_bucket[idx] = Math.max(max_bucket[idx], nums[i]);
}
// 結果
int ret = 0;
// 前一個桶的最大值
int prevMax = -1;
for (int i = 0; i < bucketSize; i++) {
// 桶裡沒有元素
if (max_bucket[i] == -1) {
continue;
}
// 計算桶間的最大值
if (prevMax != -1) {
ret = Math.max(ret, min_bucket[i] - prevMax);
}
prevMax = max_bucket[i];
}
return ret;
執行結果:
說明:
桶排序的時間複雜度和空間複雜度都為O(n)。測試用例過少,所以效率不如直接排序再遍歷求解來得高。
相關文章
- leetode【每日一題】164. 最大間距 java每日一題Java
- LeetCode 164 最大間距 HERODING的LeetCode之路LeetCode
- LeetCode每日一題: N叉樹的最大深度(No.559)LeetCode每日一題
- leetcode每日一題LeetCode每日一題
- LeetCode每日一題: 三個數的最大乘積(No.628)LeetCode每日一題
- 【Leetcode 每日一題】1030. 距離順序排列矩陣單元格(水題,曼哈頓距離排序)LeetCode每日一題矩陣排序
- LeetCode每日一題:二叉樹的最大深度(No.104)LeetCode每日一題二叉樹
- Leetcode每日一題(1)LeetCode每日一題
- 每日一道演算法題--leetcode 461--漢明距離--python演算法LeetCodePython
- LeetCode每日一題:sort colorsLeetCode每日一題
- LeetCode每日一題: 三角形的最大周長(No.976)LeetCode每日一題
- LeetCode每日一題:連結串列的中間結點(No.876)LeetCode每日一題
- LeetCode 每日一題「判定字元是否唯一」LeetCode每日一題字元
- LeetCode每日一題:Nim遊戲(No.292)LeetCode每日一題遊戲
- LeetCode每日一題: 找不同(No.389)LeetCode每日一題
- LeetCode每日一題: 移除元素(No.27)LeetCode每日一題
- leetcode-624.陣列列表中的最大距離LeetCode陣列
- 【每日一題】632. 最小區間每日一題
- 每日一題:1026. 節點與其祖先之間的最大差值每日一題
- LeetCode每日一題: 移動零(No.283)LeetCode每日一題
- LeetCode每日一題:自除數(No.728)LeetCode每日一題
- LeetCode每日一題:迴文數(No.9)LeetCode每日一題
- LeetCode每日一題:兩數之和(No.1)LeetCode每日一題
- LeetCode每日一題:爬樓梯(No.70)LeetCode每日一題
- LeetCode每日一題: 排列硬幣(No.441)LeetCode每日一題
- LeetCode每日一題: 各位相加(No.258)LeetCode每日一題
- LeetCode每日一題:longest palindromic substringLeetCode每日一題
- LeetCode 2024/6 每日一題 合集LeetCode每日一題
- leetcode刷題.763. 劃分字母區間.每日打卡LeetCode
- [每日一題] 第十五題:連續子陣列的最大和每日一題陣列
- Leetcode每日一題:面試題16.19.水域大小LeetCode每日一題面試題
- LeetCode每日一題:整數反轉(No.7)LeetCode每日一題
- LeetCode每日一題:求眾數(No.169)LeetCode每日一題
- LeetCode每日一題: 轉置矩陣(No.867)LeetCode每日一題矩陣
- LeetCode每日一題:最長公共字首(No.14)LeetCode每日一題
- LeetCode每日一題: 搜尋插入位置(No.35)LeetCode每日一題
- 【js】Leetcode每日一題-葉子相似的樹JSLeetCode每日一題
- LeetCode:每日一題:27. 移除元素 ——————簡單LeetCode每日一題