【Leetcode】164. Maximum Gap 【基数排序】

Given an unsorted array, find the maximum difference between the successive elements in its sorted form.

Return 0 if the array contains less than 2 elements.

  • Try to solve it in linear time/space.

题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-gap
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

=======================================================================

【分析】

这道题目最简单的思路就是使用自带的排序函数先排序,然后比较计算相邻量元素差值并求出最大值。时间复杂度为O(nlogn)。但题目中提到最好用线性时间复杂度来解决,引入一种更快捷的排序方法,基数排序。

基数排序:

1. 从最低位(或最高位)开始,根据每个元素该为数字大小进行排序(若该为相等的元素则维持原有的前后顺序);

2.组成新的数组后再根据高一位的数字大小对元素按相同方法进行排序;

3.直到根据数组中最大的数字的最高位排序后,即可得到一个有序数组。

Eg. 原数组:

[ 10, 22, 19, 43, 72, 1, 8, 312]

根据个位数字排序后变为: [10, 1, 22, 72, 312, 43, 8, 19]

根据十位数字排序后变为: [1, 8, 10, 312, 19, 22, 43, 72]

根据百位数字排序后变为: [1, 8, 10, 19, 22, 43, 72, 312]

【参考代码】

class Solution {
public:
    int maximumGap(vector<int>& nums) {
        int n = nums.size();
        if(n < 2) return 0;
        vector<int> aux(n, 0);
        int exp = 1;

        int maxN = *max_element(nums.begin(), nums.end());
        while(maxN/exp > 0) {
            vector<int> count(10, 0);
            for(int n: nums) {
                count[(n/exp)%10]++;
            }
            for(int i = 1; i < 10; i++) {
                count[i] += count[i-1];
            }
            for(int i = n-1; i >= 0; --i) {
                int n = nums[i];
                aux[--count[(n/exp)%10]] = n;
            }
            for(int i = 0; i < n; ++i) {
                nums[i] = aux[i];
            }
            exp *= 10;
        }
        int res = 0;

        for(int i = 1; i < n; ++i) {
            //cout << nums[i-1] << ", ";
            res = max(res, nums[i]-nums[i-1]);
        }
        return res;
    }
};

【代码分析】

使用count[d]. 先用count[d]来统计当前的位数中数字为d的元素个数,后进行处理,使count[d]表示小于等于d的元素总数

之后可从后向前遍历nums, 根据元素当前位数中的数字决定他应该在新数组(aux)中的位置:

最后一个当前位等于d的元素,应该处于count[d]-1的位置;放入该元素后,把count[d]减一,便为下一个当前位等于d的元素的位置+1。

时间复杂度:O(d*(n+10)) 约等于O(n)

猜你喜欢

转载自www.cnblogs.com/xiyang2020/p/12918637.html