线性排序算法 —— LeetCode164 最大间距

一、自带sort 324ms 排序后遍历

class Solution:
    def maximumGap(self, nums: List[int]) -> int:
        nums.sort()
        res = 0
        for i in range(1,len(nums)):
            res = max(res,nums[i]-nums[i-1])
        return res

二、基数排序 1212ms 排序后遍历

class Solution:
    def maximumGap(self, nums: List[int]) -> int:
        if len(nums) == 1:
            return 0
        n_sort = len(str(max(nums)))
        # 基数为0-9 每一个列表放以i结尾的数
        sorted_nums = [nums] # -1位排好序
        # k*n
        for i in range(n_sort):
            # 排下一位 
            cur_nums = [[] for _ in range(10)]
            # 从排好上一位结果中取数 10 
            for equal_last in sorted_nums:
                # [] n/10
                for num in equal_last:
                    idx = num // (10**i) % 10 #得到第i+1位数
                    cur_nums[idx].append(num) # 放入基数中
            sorted_nums = cur_nums
        res = []
        # n/10*10
        for equal_nums in sorted_nums:
            for num in equal_nums:
                res.append(num)
        maxdiff = 0
        # n
        for i in range(1,len(res)):
            maxdiff = max(maxdiff,res[i]-res[i-1])
        return maxdiff

三、分桶+min+max 612ms

  • 未排序+计算桶内最大最小值
class Solution:
    def maximumGap(self, nums: List[int]) -> int:
        if len(nums) < 2:
            return 0
        if len(nums) == 2:
            return nums[1]-nums[0]
        # 最大值和最小值 O(n) 
        minval = nums[0]
        maxval = nums[1]
        for i in range(len(nums)):
            if nums[i] <minval:
                minval = nums[i]
            elif nums[i]>maxval:
                maxval = nums[i]
        # 间隔<(maxval-minval/N-1)不成立 N-1个间隔<max-min
        # 令桶长等于这个即可,所以最大间隔一定是桶间
        bucket_size = max(1,(maxval-minval)//(len(nums) - 1))
        bucket_counts = max(1,(maxval - minval)//bucket_size + 1)
        # 桶
        buckets = [[] for _ in range(bucket_counts)]
        # 分桶
        for i in range(len(nums)):
            bucket_index = (nums[i] - minval) // bucket_size
            buckets[bucket_index].append(nums[i])
        # min max计算
        maxdiff = max(buckets[0]) - min(buckets[0])
        right = max(buckets[0])
        for bucket in buckets[1:]:
            if len(bucket) > 0:
                maxdiff = max(min(bucket) - right,maxdiff)
                right = max(bucket)
        return maxdiff

四、桶排序 736ms

  • 排序后遍历桶 比三 多排序操作,少求最大值最小值操作
class Solution:
    def maximumGap(self, nums: List[int]) -> int:
        if len(nums) < 2:
            return 0
        if len(nums) == 2:
            return nums[1]-nums[0]
        buckets = self.bucket_sort(nums)
        maxdiff = buckets[0][-1] - buckets[0][0]
        right = buckets[0][-1]
        for bucket in buckets[1:]:
            if len(bucket) > 0:
                maxdiff = max(bucket[0]- right,maxdiff)
                right = bucket[-1]
        return maxdiff

    def bucket_sort(self,nums):
        # 最大值和最小值 O(n) 
        minval = nums[0]
        maxval = nums[1]
        for i in range(len(nums)):
            if nums[i] <minval:
                minval = nums[i]
            elif nums[i]>maxval:
                maxval = nums[i]
        # 需要有一个空的bucket:gap=next_left-cur_right binfor10: 0 |1| 2
        bucket_size = max(1,(maxval-minval)//(len(nums) - 1))
        bucket_counts = max(1,(maxval - minval)//bucket_size + 1)
        # 桶
        buckets = [[] for _ in range(bucket_counts)]
        # 分桶
        for i in range(len(nums)):
            bucket_index = (nums[i] - minval) // bucket_size
            buckets[bucket_index].append(nums[i])
        # 排序
        res = []
        for bucket in buckets:
            # 桶内快排
            self.quick_sort(bucket,0,len(bucket)-1)
            for j in range(len(bucket)):
                res.append(bucket[j])
        return buckets

    def quick_sort(self,nums,left,right):
        if left > right:
            return
        begin = left
        end = right
        pivot = nums[(left+right)//2]
        while begin<end:
            while nums[begin] < pivot:begin+=1
            while nums[end] > pivot:end-=1
            # 发现不符合条件的两个数
            if begin<=end:
                nums[begin],nums[end] =nums[end],nums[begin]
                begin += 1
                end -= 1
        # 进入下一轮
        if begin < right:
            self.quick_sort(nums,begin,right)
        if end > left:
            self.quick_sort(nums,left,end)           

五、补充计数排序

  • 可以解决小范围,本题不适用
  • 范围远远超过数组长度
class Solution:
    def maximumGap(self, nums: List[int]) -> int:
        if len(nums) < 2:
            return 0
        minval = min(nums)
        maxval = max(nums)
        # 计数
        counts = [0] * (maxval-minval+1)
        for idx in nums:
            counts[idx-minval] += 1
        # 加入nums
        index = 0
        max_interval = 0
        right = 0
        for i in range(len(counts)):
            for j in range(counts[i]):
                nums[index] = i
                max_interval = max(max_interval, nums[index]-right)
                right = nums[index]
                index += 1
        return max_interval 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值