稳定版计数排序

相比朴素版计数排序,可以保证排序后数组中相等元素原本的先后顺序不变。

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        int n = nums.size();
        //1.得到数列的最大值和最小值,并算出差值d
        int minVal = INT_MAX, maxVal = INT_MIN;
        for (int i=0; i<n; i++) {
            minVal = min(minVal, nums[i]);
            maxVal = max(maxVal, nums[i]);
        }
        //2.创建统计数组并统计对应元素个数
        int m = maxVal - minVal + 1;
        vector<int> temp(m);
        for (int i=0; i<n; i++) {
            temp[nums[i]-minVal]++;
        }
        //3.统计数组做变形,后面的元素等于前面的元素之和
        int sum = 0;
        for (int i=0; i<m; i++) {
            sum += temp[i];
            temp[i] = sum;
        }
        //4.倒序遍历原数列,从统计数组找到正确位置,输出到结果数组
        vector<int> ans(n, 0);
        for (int i=n-1, j=0; i>=0; i--) {
            ans[temp[nums[i]-minVal]-1] = nums[i];
            temp[nums[i]-minVal]--;
        }
        return ans;
    }   
};

时间复杂度 O(n + k),n为元素个数,k 为元素的取值范围。
空间复杂度 O(k),不考虑结果数组分配空间。

计数排序的局限性:

  1. 当数列最大最小值差距过大时,并不适用计数排序。
    比如给定20个随机整数,范围在0到1亿之间,这时候如果使用计数排序,需要创建长度1亿的数组。不但严重浪费空间,而且时间复杂度也随之升高。

  2. 当数列元素不是整数,并不适用计数排序。
    如果数列中的元素都是小数,比如25.213,或是0.00000001这样子,则无法创建对应的统计数组。这样显然无法进行计数排序。

参考链接:https://mp.weixin.qq.com/s?__biz=MzIxMjE5MTE1Nw%3D%3D&chksm=8c99ffd7bbee76c1d2e2e9b198259795285ec2c305d3613a5e39622195fd1c32bb6dbe52fa08&idx=1&mid=2653195533&scene=21&sn=02918dc51b07837ce1119f00d7900dbc#wechat_redirect

发布了59 篇原创文章 · 获赞 0 · 访问量 1172

猜你喜欢

转载自blog.csdn.net/u011861832/article/details/105222683
今日推荐