数据结构【双指针、数组】| leetcode 88. 合并两个有序数组(简单)

代码链接:https://leetcode.cn/problems/merge-sorted-array/solution/fu-xue-ming-zhu-dong-hua-ti-jie-cong-hou-teq6/

本题重点:

  • 两个数组有序;
  • 合并结果放到 nums1 中

注意题目给出的数组的方式:nums1 中本身有效的数字是前 m 位,nums1 的长度是 m+n,因此正好可以放下 nums1[0:m] + nums2[0:n]。

合并两个有序数组,我们第一反应肯定是想到了归并排序。归并排序是把两个有序的数组合并、放到另外一个数组中。所以空间复杂度是 O(M+N) 的。

由于本题给出的 nums1 是能够保证其长度能够放得下 m+n 个元素的,所以可以直接把合并的结果放到 nums1 中。

  • 思路一:如果两个数组从开头向结尾(数字从小到大)进行比较,那么每次把比较之后的数字放置到 nums1 中的前面,则需要把 nums1 中第 k 个位置后面的元素向后移动。移动次数比较多。
  • 思路二:如果两个数组从结尾向开头(数字从大到小)进行比较,那么每次把比较之后的数字放置到 nums1 中的后面,由于后面的数字本身就是提供出来的多余的位置,都是 0,因此不需要对 nums1 进行移动。

显然思路二更好。

从后向前进行比较

确定了主要的思路之后,实现起来其实很简单。

1、当 m > 0 m > 0 m>0 并且 n > 0 n > 0 n>0 时,从后向前比较 n u m 1 [ m − 1 ] num1[m−1] num1[m1] n u m s 2 [ n − 1 ] nums2[n−1] nums2[n1]

  • 如果是 n u m s 1 [ m − 1 ] nums1[m−1] nums1[m1] 大,则把 n u m s 1 [ m − 1 ] nums1[m−1] nums1[m1] 放到 n u m 1 num1 num1 的第 m + n − 1 m+n−1 m+n1 位置,并让 m − = 1 m−=1 m=1
  • 如果是 n u m s 1 [ n − 1 ] nums1[n−1] nums1[n1] 大,则把 n u m s 2 [ n − 1 ] nums2[n−1] nums2[n1] 放到 n u m 1 num1 num1 的第 m + n − 1 m+n−1 m+n1 位置,并让 n − = 1 n−=1 n=1

2、当上面的遍历条件结束的时候,此时 m 和 n 至少有一个为 0。

  • m = = 0 m== 0 m==0 时,说明 n u m 1 num1 num1 的数字恰好用完了,此时 n u m s 2 nums2 nums2 可能还剩元素,需要复制到 n u m s 1 nums1 nums1 的头部;
  • n = = 0 n== 0 n==0 时,说明 n u m 2 num2 num2 的数字恰好用完了,此时 n u m s 1 nums1 nums1 可能还剩元素,由于剩余的这些元素一定是 n u m s 1 nums1 nums1 n u m s 2 nums2 nums2 中最小的元素,所以不用动,直接留在原地就行。
class Solution:
    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        """
        Do not return anything, modify nums1 in-place instead.
        """
        k = m+n-1
        while m > 0 and n > 0:
            if nums1[m-1] <= nums2[n-1]:
                nums1[k] = nums2[n-1]
                n -= 1
            else:
                nums1[k] = nums1[m-1]
                m -= 1
            k -= 1
        if m == 0:
            nums1[:n] = nums2[:n]

复杂度分析:

  • 时间复杂度: O ( m + n ) O(m+n) O(m+n)。指针移动单调递减,最多移动 m + n m+n m+n 次,因此时间复杂度为 O ( m + n ) O(m+n) O(m+n)
  • 空间复杂度: O ( 1 ) O(1) O(1)。直接对数组 n u m s 1 {nums}_1 nums1原地修改,不需要额外空间。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值