算法刷题打卡第48天:排序数组---基数排序

排序数组

难度:中等

给你一个整数数组 nums,请你将该数组升序排列。

示例 1:

输入:nums = [5,2,3,1]
输出:[1,2,3,5]

示例 2:

输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]

基数排序

思路:
常见的数据元素一般是由若干位组成的,比如字符串由若干字符组成,整数由若干位 0~9 数字组成。基数排序按照从右往左的顺序,依次将每一位都当做一次关键字,然后按照该关键字对数组的元素入桶,每一轮入桶都基于上轮入桶的结果;完成所有位的入桶后,整个数组就达到有序状态。

比如对于数字2985,从右往左就是先以个位为关键字进行入桶,然后是十位、百位、千位。总共需要四轮。基数排序也是一种无需比较的排序算法。

样例如下:

时间复杂度: O ( d ( n + r ) ) O(d(n+r)) O(d(n+r))
空间复杂度: O ( n + r ) O(n+r) O(n+r)
注: 基数排序的复杂度中, r r r 代表关键字的基数, d d d 代表统计需要进行的轮次(最大最小值数值部分的长度), n n n 代表数组的个数。

class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        # 统计需要进行的轮次(最大最小值数值部分的长度)
        size = max(len(str(abs(max(nums)))), len(str(abs(min(nums)))))
        # 基数排序
        for i in range(size):
            # 初始化桶
            num_stack = [[] for _ in range(10)]
            for x in nums:
                # 这里改进一下采用绝对值进行入桶,方面后续对负数处理
                num_stack[abs(x) // 10**i % 10].append(x)
            # 将入桶元素按顺序取出重新复制到数组
            nums = [num for stack in num_stack for num in stack]

        # 使用双端队列处理正负数的问题
        # 如果大于0,那就是使用队尾入队,反之使用队头入队
        res = collections.deque()
        for num in nums:
            if num > 0:
                res.append(num)
            else:
                res.appendleft(num)
        return list(res)

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/sort-an-array

你可能感兴趣的:(躺平合集,算法,leetcode,数据结构,基数排序)