LeetCode0088

38 篇文章 0 订阅
26 篇文章 0 订阅
  1. 题目:合并两个有序数组

  2. 题目解释:

    给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。

    初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。你可以假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2 的元素。

    示例 1:

    ​ 输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
    ​ 输出:[1,2,2,3,5,6]
    示例 2:

    ​ 输入:nums1 = [1], m = 1, nums2 = [], n = 0
    ​ 输出:[1]

    提示:

    • nums1.length == m + n
    • nums2.length == n
    • 0 <= m, n <= 200
    • 1 <= m + n <= 200
    • -109 <= nums1[i], nums2[i] <= 109
  3. 解法一:合并两个数组之后排序

    代码:

    class Solution(object):
        def merge(self, nums1, m, nums2, n):
            """
            :type nums1: List[int]
            :type m: int
            :type nums2: List[int]
            :type n: int
            :rtype: void Do not return anything, modify nums1 in-place instead.
            """
            nums1[:] = sorted(nums1[:m] + nums2)
    
    • 时间复杂度 : O((n + m)log(n+m))。
    • 空间复杂度 : O(1)。
  4. 解法二:双指针法。(从前往后)

    代码:

    class Solution:
        def merge(self, nums1, m: int, nums2, n: int) -> None:
    
            #由于题目要求nums1是合并后的数组,所以我们在这里需要对nums1进行拷贝,然后清空
            nums1_copy = nums1[:m]
            nums1[:] = []
    
            # Two get pointers for nums1_copy and nums2.
            p1 = 0
            p2 = 0
    
            #遍历时,如果nums1还有元且nums2还有元素,则将较小的追加到nums1中,注意是且的关系
            while p1 < m and p2 < n:
                if nums1_copy[p1] < nums2[p2]:
                    nums1.append(nums1_copy[p1])
                    p1 += 1
                else:
                    nums1.append(nums2[p2])
                    p2 += 1
    
            #如果其中一个为空,则直接追加
            if p1 < m:
                nums1[p1 + p2:] = nums1_copy[p1:]
            if p2 < n:
                nums1[p1 + p2:] = nums2[p2:]
    
            return nums1
    
    
    nums1 = [1, 2, 3, 0, 0, 0]
    m = 3
    nums2 = [2, 5, 6]
    n = 3
    a = Solution()
    print(a.merge(nums1, m, nums2, n))
    

    复杂度分析

    • 时间复杂度 : O(n + m)。
    • 空间复杂度 : O(m)。
  5. 解法三:双指针法。(从后往前)

    代码:

    class Solution(object):
        def merge(self, nums1, m, nums2, n):
            """
            :type nums1: List[int]
            :type m: int
            :type nums2: List[int]
            :type n: int
            :rtype: void Do not return anything, modify nums1 in-place instead.
            """
            # two get pointers for nums1 and nums2,都是指向末尾
            p1 = m - 1
            p2 = n - 1
            #设置nums1的指针,但这个指针是指向nums1的最后一个空间
            p = m + n - 1
    
            # while there are still elements to compare
            #如果p1和p2中的两个指针都没有逆向将各自的数组遍历完,则进行比较排序
            while p1 >= 0 and p2 >= 0:
                if nums1[p1] < nums2[p2]:
                    nums1[p] = nums2[p2]
                    p2 -= 1
                else:
                    nums1[p] = nums1[p1]
                    p1 -= 1
                p -= 1
    
            # add missing elements from nums2
            #如果p1先遍历完nums1,则将nums2的元素添加到nums1的开头
            #如果p2先遍历完,则p2 = -1,此时nums2[:p2+1] = nums2[:0],
            # 区间左闭右开,所以此条语句无用,此时数组已然有序。
            nums1[:p2 + 1] = nums2[:p2 + 1]
            return nums1
    nums1 = [1, 3, 0, 0, 0]
    m = 2
    nums2 = [2, 5, 6]
    n = 3
    a = Solution()
    print(a.merge(nums1, m, nums2, n))
    

    复杂度分析

    • 时间复杂度 : O(n + m)。
    • 空间复杂度 : O(1)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值