菜鸟python刷力扣题__3_合并排序的数组

本文深入探讨了两个已排序数组的合并及排序算法,提供三种实现方法:直接合并排序、逆向双指针优化及双向指针优化。通过对比分析,阐述了不同方法的时间和空间复杂度,帮助读者理解算法原理及优化思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.描述:
给定两个排序后的数组 A 和 B,其中 A 的末端有足够的缓冲空间容纳 B。 编写一个方法,将 B 合并入 A 并排序。

初始化 A 和 B 的元素数量分别为 m 和 n。

示例:

输入:
A = [1,2,3,0,0,0], m = 3
B = [2,5,6],       n = 3

输出: [1,2,2,3,5,6]

2.理解
用python最直接的想法是将B并入到A后面,然后调用sort方法,一开始很怀疑不会通过,结果试了试,发现还真行…

当然,仅仅pass并不是目的。已知该题目中两个序列已经有序,我们可以设置两个指针,分别指向A和B开头,然后比较两个值,根据不同情况对指针进行后移。但是如果直接对A从前往后进行操作显然数据移位时浪费大量时间,而且依据题意,不能使用第三个序列 (这是我的思维误区,其实可以先添加一个序列,最后将结果赋给A就行…)
所以在之前猜想的基础上,我们可以将指针设置成从后往前,每次将最大的数放入A的最末端,此时最坏的时间复杂度为O(n+m)。

3.答题:
3.1简单的想法

class Solution(object):
    def merge(self, A, m, B, n):
        """
        :type A: List[int]
        :type m: int
        :type B: List[int]
        :type n: int
        :rtype: None Do not return anything, modify A in-place instead.
        """
        for i in range(m,m+n):
            A[i]=B[i-m]
        A.sort()

执行时间24 ms,消耗内存11.8 MB。

3.2逆双向指针

class Solution(object):
    def merge(self, A, m, B, n):
        """
        :type A: List[int]
        :type m: int
        :type B: List[int]
        :type n: int
        :rtype: None Do not return anything, modify A in-place instead.
        """
        p_a = m-1 # 指向A的有序数字末尾
        p_b = n-1 # 指向B的有序数字末尾
        p = m+n-1 # 指向A序列末尾
        while p_a >= 0 and p_b >= 0: # 当a和b里面数据都未遍历完时
            if A[p_a] > B[p_b]:
                A[p] = A[p_a]
                p -= 1
                p_a -= 1
            else:
                A[p] = B[p_b]
                p -= 1
                p_b -= 1
        while p_a < 0 and p_b >= 0: # 此时是a中的数据已经遍历完
            A[p_b] = B[p_b]
            p_b -= 1

执行时间20 ms,消耗内存11.7 MB。

3.3双向指针:利用指针从前往后

class Solution(object):
    def merge(self, A, m, B, n):
        """
        :type A: List[int]
        :type m: int
        :type B: List[int]
        :type n: int
        :rtype: None Do not return anything, modify A in-place instead.
        """
        p_a = 0
        p_b = 0
        p = 0
        result = (m+n)*[0]
        while p_a < m and p_b < n:
            if A[p_a] > B[p_b]:
                result[p] = B[p_b]
                p += 1
                p_b += 1
            else:
                result[p] = A[p_a]
                p += 1
                p_a += 1
        while p_a == m and p_b < n:
            result[p] = B[p_b]
            p += 1
            p_b += 1
        while p_a < m and p_b == n:
            result[p] = A[p_a]
            p += 1
            p_a += 1
        A[:] = result

其实后面两种方法原理类似。只不过我的写法有些憨憨…尚且有优化空间。

题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sorted-merge-lcci

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值