Maximum Gap
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.
Naive Way: 最初的想法是如果能排序,就能一次遍历求得最大gap,但是排序就是O(nlogn)了。要求在O(n)的时间内做出,唯一能利用的就是O(n)的space了。考虑最坏的情况是所有数字都具有相同间隔,比如[1 3 5 7 9],在不改变区间范围的情况下,任意改变其中某个数都会使结果变大,也就是说,如果能确定数组的区间范围,(max-min)/size 就是最差的情况,任意有数不是在分割点上,说明本该在那个分割点上的数改变了,max gap也就改变了。
举个例子说明:[1,4,5,7,9]
最大是1,最小是9,一共5个数。5个数应该有4个分区,(平均分)。然后遍历一遍数组将每个数字归入自己所在分区。
[1,3)-> 最小值是1,最大值是1。
[3,5)-> 最小值是4,最大值是4。
[5,7)-> 最小值是5,最大值是5。
[7,9]-> 最小值是7,最大值是9。
这样就可以知道一旦某一区段最小值不是区段下限,就可以知道max gap 可能由它产生。遍历一遍区段,一旦有以上情况就要左右追溯,找出可能的max gap。
算法复杂度可以达到O(n), space O(n)。
public class Solution {
public int maximumGap(int[] num) {
int maxGap = 0;
// edge case
if(num.length < 2) return maxGap;
// find min and max
int min = num[0], max = min;
for(int i = 1;i < num.length;i++){
min = Math.min(min,num[i]);
max = Math.max(max,num[i]);
}
// form gaps
int dis = (max-min)/(int)Math.min(max-min,num.length-1);
List<List<Integer>> gaps = new ArrayList<List<Integer>>();
for(int i = 0;i < (max-min)/dis;i++){
List<Integer> gap = new ArrayList<Integer>();
gap.add(-1);
gap.add(-1);
gaps.add(gap);
}
// fill in gaps
for(int i = 0;i < num.length;i++){
List<Integer> gap = gaps.get((int)Math.min(gaps.size()-1,(num[i]-min)/dis));
if(gap.get(0)==-1) gap.set(0,num[i]);
else gap.set(0,Math.min(num[i],gap.get(0)));
if(gap.get(1)==-1) gap.set(1,num[i]);
else gap.set(1,Math.max(num[i],gap.get(1)));
}
// find maximum gap
for(int i = 0;i < gaps.size();i++){
List<Integer> gap = gaps.get(i);
if(gap.get(0)==-1) continue; // means current gap is empty
int j = i-1;
// traversal lower level gaps
while(j >= 0 && gaps.get(j).get(1)==-1) j--;
if(j>=0) maxGap = Math.max(maxGap, gap.get(0)-gaps.get(j).get(1));
// traversal upper level gaps
j = i+1;
while(j < gaps.size() && gaps.get(j).get(0)==-1) j++;
if(j<gaps.size()) maxGap = Math.max(maxGap, gaps.get(j).get(0)-gap.get(1));
// edge case for one gap
maxGap = Math.max(maxGap, gap.get(1)-gap.get(0));
}
return maxGap;
}
}
Improved Way:这种方法原来叫做bucket sort,原是一种排序的算法,特别适合用来求Gap。Discuss里无一例外全是这种方法,但是施行的也有好有坏,写得最好的我觉得是下面这个。
来自leetcode用户
No comments:
Post a Comment