LeetCode 题解(84): 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.

Credits:
Special thanks to @porker2008 for adding this problem and creating all test cases.

题解:

基本思路,linear time / space, bucked sort。

Maximum Gap >= ceil [(maxValue - minValue) / (N - 1)]  > ceil [(maxValue - minValue) / (N - 1)] - 1 = Maximum difference if we choose bucket size as: ceil [(maxValue - minValue) / (N - 1)]. 所以如果选择bucket_size = ceil [(maxValue - minValue) / (N - 1)],我们可以保证Maximum Gap一定不在同一个Bucket里。那么Maximum Gap一定是后一个非空桶的最小值减去前一个非空桶的最大值,然后取这些相邻桶间差值的最大值。

三个核心变量:

Bucket_size = ceil [(maxValue - minValue) / (N - 1)]

Bucket_num = (maxValue - minValue) / Bucket_size + 1

index = (num[i] - minValue) / Bucket_size


桶里只需要存该桶的最小值和最大值即可。


C++版:

class Solution {
public:
    int maximumGap(vector<int>& nums) {
        if(nums.size() < 2)
            return 0;
        
        int max = 0, min = INT_MAX;
        for(auto i: nums) {
            max = i > max ? i : max;
            min = i < min ? i : min;
        }
        
        int bucket_size = (max - min) / (nums.size() - 1) + 1;
        int bucket_num = (max - min) / bucket_size + 1;
        
        vector<vector<int>> buckets(bucket_num);
        
        for(auto i: nums) {
            int index = (i - min) / bucket_size;
            if(buckets[index].empty()) {
                buckets[index].push_back(i);
                buckets[index].push_back(i);
            } else {
                buckets[index][0] = i < buckets[index][0] ? i : buckets[index][0];
                buckets[index][1] = i > buckets[index][1] ? i : buckets[index][1];
            }
        }
        
        int prev = 0;
        int maxGap = 0;
        
        if(buckets.size() == 1)
            return buckets[0][1] - buckets[0][0];
        
        for(int i = 0; i < buckets.size(); i++) {
            if(buckets[i].empty())
                continue;
            prev = i;
            int j;
            for(j = i + 1; j < buckets.size(); j++)
                if(!buckets[j].empty())
                    break;
            if(j < buckets.size() && buckets[j][0] - buckets[prev][1] > maxGap) {
                maxGap = buckets[j][0] - buckets[prev][1];
                prev = i;
                i = j - 1;
            }
        }
        
        return maxGap;
    }
    
};

Java版:

public class Solution {
    public int maximumGap(int[] num) {
        if(num.length < 2)
            return 0;
        
        int max = num[0], min = num[0];
        for(int i = 1; i < num.length; i++) {
            if(num[i] > max)
                max = num[i];
            if(num[i] < min)
                min = num[i];
        }
    
        int bucket_size = (max - min) / (num.length - 1) + 1;
        int bucket_num = (max - min) / bucket_size + 1;
        
        List<List<Integer>> buckets = new ArrayList<>();
        for(int i = 0; i < bucket_num; i++) {
            List<Integer> temp = new ArrayList<>();
            buckets.add(temp);
        }
        
        for(int i = 0; i < num.length; i++) {
            int index = (num[i] - min) / bucket_size;
            if(buckets.get(index).isEmpty()) {
                buckets.get(index).add(num[i]);
                buckets.get(index).add(num[i]);
            } else {
                if(buckets.get(index).get(0) > num[i])
                    buckets.get(index).set(0, num[i]);
                if(buckets.get(index).get(1) < num[i])
                    buckets.get(index).set(1, num[i]);
            }
        }
        
        int maxGap = 0;
        
        if(buckets.size() == 1) {
            return buckets.get(0).get(1) - buckets.get(0).get(0);
        }
        int prev = 0;
        for(int i = 0; i < buckets.size() - 1; i++) {
            if(buckets.get(i).isEmpty())
                continue;
            prev = i;
            int j;
            for(j = i + 1; j < buckets.size(); j++)
                if(!buckets.get(j).isEmpty())
                    break;
            
            if(j < buckets.size() && buckets.get(j).get(0) - buckets.get(i).get(1) > maxGap) {
                maxGap = buckets.get(j).get(0) - buckets.get(i).get(1);
                prev = j;
                i = j - 1;
            }
        }
        
        return maxGap;
    }
}

Python版:

class Solution:
    # @param {integer[]} nums
    # @return {integer}
    def maximumGap(self, nums):
        if len(nums) < 2:
            return 0
        maxValue = max(nums)
        minValue = min(nums)
        
        bucket_size = int((maxValue - minValue) / (len(nums) - 1)) + 1
        bucket_num = int((maxValue - minValue) / bucket_size )+ 1
        
        buckets = [None] * bucket_num
        
        for i in nums:
            index = int((i - minValue) / bucket_size)
            if buckets[index] == None:
                buckets[index] = {'min':i, 'max':i}
            else:
                if i < buckets[index]['min']:
                    buckets[index]['min'] = i
                if i > buckets[index]['max']:
                    buckets[index]['max'] = i
                    
        maxGap = 0
        
        if bucket_num == 1:
            return buckets[0]['max'] - buckets[0]['min']
            
        for i in range(bucket_num):
            if buckets[i] == None:
                continue
            j = i + 1
            while j < bucket_num and buckets[j] == None:
                j += 1
            
            if j < bucket_num and buckets[j]['min'] - buckets[i]['max'] > maxGap:
                maxGap = buckets[j]['min'] - buckets[i]['max']
            
            i = j
        
        return maxGap

你可能感兴趣的:(Algorithm,LeetCode,面试题)