1.題目
給定一個數組,求如果排序之後,相鄰兩數的最大差值,要求時間複雜度O(N),且要求不能用非基於比較的排序。
2.實現
2.1 思路
問題:
* 給定一個數組,求如果排序之後,相鄰兩數的最大差值,要求時間複雜度O(N),且要求不能用非基於比較的 排序。
* 比如 數組[1,2,9,4,6] sort後 [1,2,4,6,9] 6-9之間間隙最大值就爲3.
* 思路:
* 我們可以基於桶排序的思想來解決這個問題。data[1,2,3,4,5,7,8] 那麼最大值就爲2 5->7之間的最大間隙爲2
* a.首先創建一個n+1 大小的桶,遍歷一遍數組 找出minValue 和 maxValue。如果最大值和最小值相等 說明數據一樣 直接返回
* 將minValue放在下標爲0的桶的位置 maxValue放在下標爲n的桶位置。
* b.創建三個數組 分別記錄 存放的是hasNum->是否有數據 minNum ->最小值 maxNum ->最大值
* 遍歷將數據放在每個桶的位置上,桶只存儲三個屬性,是否有數據 最小值 最大值。
* c.如此 如果想找出間隙最大值,試想是不可能出現在同一個桶類,只會在相鄰桶之間 也就是 左桶的最大值 和 油桶的 最小值
*
* 複雜度分析
* time : O(n)
* space : O(1)
2.2 code
package com.ncst.base.one;
/**
* @author i
* @create 2020/5/9 19:29
* @Description
*
* 問題:
* 給定一個數組,求如果排序之後,相鄰兩數的最大差值,要求時間複雜度O(N),且要求不能用非基於比較的排序。
* 思路:
* 我們可以基於桶排序的思想來解決這個問題。data[1,2,3,4,5,7,8] 那麼最大值就爲2 5->7之間的最大間隙爲2
* a.首先創建一個n+1 大小的桶,遍歷一遍數組 找出minValue 和 maxValue。如果最大值和最小值相等 說明數據一樣 直接返回
* 將minValue放在下標爲0的桶的位置 maxValue放在下標爲n的桶位置。
* b.創建三個數組 分別記錄 存放的是hasNum->是否有數據 minNum ->最小值 maxNum ->最大值
* 遍歷將數據放在每個桶的位置上,桶只存儲三個屬性,是否有數據 最小值 最大值。
* c.如此 如果想找出間隙最大值,試想是不可能出現在同一個桶類,只會在相鄰桶之間 也就是 左桶的最大值 和 油桶的 最小值
*
* 複雜度分析
* time : O(n)
* space : O(1)
*/
public class MaxGap {
public static int maxGap(int[] arr) {
//1.參數判斷
if (arr == null || arr.length <= 2) {
return 0;//表示沒有
}
int minValue = Integer.MIN_VALUE;
int maxValue = Integer.MAX_VALUE;
//2.遍歷元素 找出minValue 和 maxValue
for (int value : arr) {
minValue = Math.min(minValue, value);
maxValue = Math.max(maxValue, value);
}
if (maxValue == minValue) {
return 0;
}
//3.比較 找出間隙最大值
int n = arr.length;
boolean[] hasNum = new boolean[n + 1];
int[] maxNum = new int[n + 1];
int[] minNum = new int[n + 1];
//3.1 將每個元素存儲到所屬的桶內
//記錄桶的下標
int bid = 0;
for (int i = 0; i < n; i++) {
bid = bucket(arr[i], n, minValue, maxValue);
//找到最小值
minNum[bid] = hasNum[bid] ? Math.min(arr[i], minNum[bid]) : arr[i];
//找到最大值
maxNum[bid] = hasNum[bid] ? Math.max(arr[i], maxNum[bid]) : arr[i];
hasNum[bid] = true;
}
//3.2 找到間隙最大值
int res = 0;
int lastIndex = maxNum[0];
for (int i = 1; i <= n; i++) {
if (hasNum[i]) {
res = Math.max(res, minNum[i] - lastIndex);
lastIndex = maxNum[i];
}
}
return res;
}
/***
*
* @param num
* @param len
* @param min
* @param max
* @return
*/
public static int bucket(long num, long len, long min, long max) {
return (int) ((num - min) * len / (max - min));
}
}