原题:
Given an unsorted array, find the maximum difference between the successive elements in its sorted form.
Try to solve it in linear time/space.
Return 0 if the array contains less than 2 elements.
You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.
地址:https://leetcode.com/problems/maximum-gap/
在常数时间和空间复杂度内实现排序,基数排序的时间复杂度为O(kn),k为最大的数字的位数,n为数字总数,空间复杂度为O(n)。
基数排序的模拟过程可以参考:https://www.cs.usfca.edu/~galles/visualization/RadixSort.html
下面是本题的解法(未经优化):
public int maximumGap(int[] nums) {
if(nums.length<2){
return 0;
}
//基数排序中,数字的位数决定基数排序的趟数,找到最大的数,确定其位数
int max = nums[0];
for(int i=0;i<nums.length;i++){
if(max<nums[i]){
max = nums[i];
}
}
int bit = 0; //最大的数一共有bit位
while(max>0){
max /= 10;
bit++;
}
//设置10个桶,因为0-9一共10个数字
ArrayList<Integer>[] buckets = new ArrayList[10];
for(int i=0;i<buckets.length;i++){
buckets[i] = new ArrayList<Integer>();
}
int n = 1;
while(n<=bit){
//放入桶中
for(int i=0;i<nums.length;i++){
int ni = (int)(nums[i]%(Math.pow(10, n))/Math.pow(10, n-1));//取第n位
buckets[ni].add(nums[i]);
}
//重新填装原来的数组,注意每个链表(桶)中元素的顺序不能变
int index = 0;
for(int i=0;i<buckets.length;i++){
for(int j=0;j<buckets[i].size();j++){
nums[index++] = buckets[i].get(j);
}
}
//把桶清空
for(int i=0;i<buckets.length;i++){
buckets[i].clear();
}
n++;
}
int maxGap = 0;
for(int i=1;i<nums.length;i++){
if(nums[i]-nums[i-1]>maxGap){
maxGap = nums[i]-nums[i-1];
}
}
return maxGap;
}
下面是leetcode中一个解答,mark一下,有空看:
public class Solution {
public int maximumGap(int[] nums) {
if (nums == null || nums.length < 2) {
return 0;
}
// m is the maximal number in nums
int m = nums[0];
for (int i = 1; i < nums.length; i++) {
m = Math.max(m, nums[i]);
}
int exp = 1; // 1, 10, 100, 1000 ...
int R = 10; // 10 digits
int[] aux = new int[nums.length];
while (m / exp > 0) { // Go through all digits from LSB to MSB
int[] count = new int[R];
for (int i = 0; i < nums.length; i++) {
count[(nums[i] / exp) % 10]++;
}
for (int i = 1; i < count.length; i++) {
count[i] += count[i - 1];
}
for (int i = nums.length - 1; i >= 0; i--) {
aux[--count[(nums[i] / exp) % 10]] = nums[i];
}
for (int i = 0; i < nums.length; i++) {
nums[i] = aux[i];
}
exp *= 10;
}
int max = 0;
for (int i = 1; i < aux.length; i++) {
max = Math.max(max, aux[i] - aux[i - 1]);
}
return max;
}