归并排序 递归 leetcode215题 性能分析(时间空间复杂度)

背景

在这里插入图片描述

解题

用归并排序

在这里插入图片描述
归并就是分解再合并的过程,主要涉及两个函数
一个是分解
一个是合并两个子数组

class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        Solution.mergeSort(nums)
        return nums[k-1]

    def mergeSort(nums:List[int]):
        n = len(nums)
        # 剩一个或没有直接返回,不用排序
        if n < 2:
            return
        # 拆分
        mid = n // 2
        s1 = nums[0:mid]
        s2 = nums[mid:n]
        # 子序列递归调用排序
        Solution.mergeSort(s1)
        Solution.mergeSort(s2)
        # 合并
        Solution.merge(s1,s2,nums)

    def merge(s1,s2,s):
        """将两个列表是s1,s2按顺序融合为一个列表s,s为原列表"""
        # j和i就相当于两个指向的位置,i指s1,j指s2
        i = j = 0
        while i+j<len(s):
            # j==len(s2)时说明s2走完了,或者s1没走完并且s1中该位置是最小的
            if j==len(s2) or (i<len(s1) and s1[i]>s2[j]):
                s[i+j] = s1[i]
                i += 1
            else:
                s[i+j] = s2[j]
                j += 1

性能分析

这里还是引用王争的分析

我们假设对 n 个元素进行归并排序需要的时间是 T(n),那分解成两个子数组排序的时间都是 T(n/2)。

我们知道,merge() 函数合并两个有序子数组的时间复杂度是 O(n)。所以,套用前面的公式,归并排序的时间复杂度的计算公式就是:

T(1) = C; n=1时,只需要常量级的执行时间,所以表示为C。
T(n) = 2*T(n/2) + n; n>1

通过这个公式,如何来求解 T(n) 呢?还不够直观?那我们再进一步分解一下计算过程。

T(n) 
= 2*T(n/2) + n = 2*(2*T(n/4) + n/2) + n 
= 4*T(n/4) + 2*n 
= 4*(2*T(n/8) + n/4) + 2*n
= 8*T(n/8) + 3*n = 8*(2*T(n/16) + n/8) + 3*n 
= 16*T(n/16) + 4*n 
...... 
= 2^k * T(n/2^k) + k * n 
......

通过这样一步一步分解推导,我们可以得到 T(n) = 2^k * T(n/2^k)+kn。

中间那项 T(n/2^k)=T(1) 时,也就是 n/2^k=1,我们得到 k=log2n 。

我们将 k 值代入上面的公式,得到 T(n)=Cn+nlog2n 。

如果我们用大 O 标记法来表示的话,T(n) 就等于 O(nlogn)。
所以归并排序的时间复杂度是 O(nlogn)。从我们的原理分析和代码可以看出,归并排序的执行效率与要排序的原始数组的有序程度无关,所以其时间复杂度是非常稳定的,不管是最好情况、最坏情况,还是平均情况,时间复杂度都是 O(nlogn)

空间复杂度是 O(n)。 - 缺点

在比较合并的时候依然可以选择顺序,所以归并是稳定的排序

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值