【leetcode刷题】面试经典150题 88.合并两个有序数组

leetcode刷题
面试经典150
88. 合并两个有序数组
难度:简单

一、题目内容

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

  • 注意:
    • 最终,合并后数组不应由函数返回,而是存储在数组 nums1 中
    • 为了应对这种情况:
    • nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,
    • nums2 的长度为 n

二、自己实现代码

2.1 实现思路

  • 可以直接将 num2覆盖到 num1的后n个元素上
  • 借助python的sort函数,一键实现排序

2.2 实现代码

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: None Do not return anything, modify nums1 in-place instead.
        """
        for i in range(n):
            nums1[i+m] = nums2[i]
        nums1.sort()

2.3 结果分析

在这里插入图片描述

三、 官方解法

感觉直接调用sort算是取巧了,官方一定不希望这样解出来,所以,把官方解法也放过来了

3.1 直接合并后排序

3.1.1 算法实现

先将数组 nums2 放进数组 nums1 的尾部,然后直接对整个数组进行排序

3.1.2 代码实现

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.
        """
        nums1[m:] = nums2
        nums1.sort()

3.1.3 代码分析

  • 时间复杂度:O((m+n)log⁡(m+n))
    排序序列长度为 m+n,套用快速排序的时间复杂度即可,平均情况为 O((m+n)log⁡(m+n))

  • 空间复杂度:O(log⁡(m+n))
    排序序列长度为 m+n,套用快速排序的空间复杂度即可,平均情况为 O(log⁡(m+n))

3.2 双指针

3.2.1 算法实现

  • 利用num1和num2都是排好序的性质,使用双指针方法
  • 将两个数组看作队列,每次从两个数组头部取出比较小的数字放到结果中
  • 具体思路
    • 首先,两个初始位置都是0
    • 然后,声明一下新的list,后面用来覆盖掉num1
    • 开始比较第一个位置上的值,取min的放入new_list中
    • 遍历结束停止

3.2.2 代码实现

3.2.2.1 错误版本1
  • 是自己对着这个思路实现的
  • 但是,忽略了两个list存在比较结束的情况
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.
        """
        p = 0
        q = 0
        new_list = []
        while p<m or q<n:
        	if num1[p] <= num2[q]:
        		new_list.append(num1[p])
        		p += 1
			else:
				new_list.append(num2[q])
        		q += 1
		num1 = new_list
3.2.2.2 错误版本2
  • 添加上了两个list存在比较结束的情况
  • 对于list的覆盖,不能直接相等
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.
        """
        p = 0
        q = 0
        new_list = []
        while p<m or q<n:
            if p == m:
                new_list.append(nums2[q])
                q += 1
            elif q == n:
                new_list.append(nums1[p])
                p +=1
            elif nums1[p] <= nums2[q]:
        		new_list.append(nums1[p])
        		p = p+1
            else:
				new_list.append(nums2[q])
				q += 1  
        nums1 = new_list

在这里插入图片描述

3.2.2.3 正确版本
  • 对于list的覆盖,不能直接相等
  • nums1[:] = new_list
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.
        """
        p = 0
        q = 0
        new_list = []
        while p<m or q<n:
            if p == m:
                new_list.append(nums2[q])
                q += 1
            elif q == n:
                new_list.append(nums1[p])
                p +=1
            elif nums1[p] <= nums2[q]:
        		new_list.append(nums1[p])
        		p = p+1
            else:
				new_list.append(nums2[q])
				q += 1  
        nums1[:] = new_list

在这里插入图片描述

3.2.3 代码分析

  • 时间复杂度:O(m+n)

  • 空间复杂度:O(m+n)

3.3 逆指针

3.3.1 算法实现

先将数组 nums2  放进数组 nums1  的尾部,然后直接对整个数组进行排序

3.3.2 代码实现

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.
        """
        p1, p2 = m - 1, n - 1
        tail = m + n - 1
        while p1 >= 0 or p2 >= 0:
            if p1 == -1:
                nums1[tail] = nums2[p2]
                p2 -= 1
            elif p2 == -1:
                nums1[tail] = nums1[p1]
                p1 -= 1
            elif nums1[p1] > nums2[p2]:
                nums1[tail] = nums1[p1]
                p1 -= 1
            else:
                nums1[tail] = nums2[p2]
                p2 -= 1
            tail -= 1

3.1.3 代码分析

  • 时间复杂度:O((m+n)

  • 空间复杂度:O(1)

四、一些注意的地方

  1. 直接使用sort可以让时间更快, 但是空间复杂度会高
  2. 考虑指针的情况下,时间复杂度和空间复杂度会减小
  3. 在看到list有顺序的时候,可以考虑增加一下指针
  4. 从小到大取,会增加新的list,造成不必要的资源浪费
  5. 在单个list空间位置够的情况下,可以优先考虑逆指针,倒着走max放后面
  6. 给list赋list, 需要 nums[:] = new_list

第三部分参考官方题解:

  • 链接:https://leetcode.cn/problems/merge-sorted-array/solutions/666608/he-bing-liang-ge-you-xu-shu-zu-by-leetco-rrb0/

相关推荐

  1. LeetCode 面试经典150 88.合并有序数组

    2024-06-16 14:08:06       17 阅读
  2. Leetcode面试经典150_Q88合并有序数组

    2024-06-16 14:08:06       11 阅读
  3. 日常88-合并有序数组

    2024-06-16 14:08:06       19 阅读
  4. LeetCode记录】简单篇-88-合并有序数组

    2024-06-16 14:08:06       9 阅读
  5. 力扣面试15088.合并有序数组

    2024-06-16 14:08:06       27 阅读
  6. 面试常考150】1、88合并有序数组

    2024-06-16 14:08:06       32 阅读
  7. 【力扣经典面试合并有序数组

    2024-06-16 14:08:06       32 阅读
  8. 1.1 面试经典 150 -合并有序数组

    2024-06-16 14:08:06       30 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-16 14:08:06       10 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-16 14:08:06       12 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-16 14:08:06       11 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-16 14:08:06       14 阅读

热门阅读

  1. c++题目_第K小的数(进阶)

    2024-06-16 14:08:06       5 阅读
  2. [AIGC] 深入浅出 Python中的`enumerate`函数

    2024-06-16 14:08:06       9 阅读
  3. 刷题 ——反转链表(若有其它解法,继续补充)

    2024-06-16 14:08:06       10 阅读
  4. wordpress站群搭建1需求分析

    2024-06-16 14:08:06       7 阅读
  5. git子模块应用和常用用法

    2024-06-16 14:08:06       6 阅读
  6. MySQL每日备份

    2024-06-16 14:08:06       6 阅读
  7. C++ 取近似值

    2024-06-16 14:08:06       9 阅读
  8. GO语言容器大全(附样例代码)

    2024-06-16 14:08:06       6 阅读
  9. linux下nvidia驱动安装-ubuntu22.04安装2060-notebook驱动

    2024-06-16 14:08:06       8 阅读
  10. 如何基于Redis实现消息队列

    2024-06-16 14:08:06       5 阅读
  11. JVM-GC-基础知识

    2024-06-16 14:08:06       7 阅读
  12. 差分,LeetCode 2779. 数组的最大美丽值

    2024-06-16 14:08:06       8 阅读