LeetCode 0088 合并两个有序数组


1. 题目


要求:直接修改nums1而不是返回数组。

自己一开始新定义了一个数组res,然后进行赋值:nums1 = res,结果样例报错。
原因是Python的Assignment操作不复制对象,我的方法只是创建了一个新的局部变量nums1,而原先传过来的nums1并没有被改变。

自己的思路

既然无法创建新的数组,就只能在原先的nums1上进行操作了。第一时间的思路是定义3个指针,i和j分别用来遍历nums1nums2的所含元素,k用来填充和修改nums1
而从小到大进行双指针归并是不可能的,因为会造成nums1数组的元素丢失。但是从后往前归并是不会丢失数据的,因为nums1的指针k移动速度永远赶不上指针i的位置。
自己所写的代码:

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.
        """
        if n == 0:
            return None
        elif m == 0:
            for i in range(n):
                nums1[i] = nums2[i]
            return None
        else:
            i , j, k = m-1 , n-1, m+n-1
            while i >= 0  and j >= 0:
                if nums1[i] <= nums2[j]:
                    nums1[k] = nums2[j]
                    j -= 1
                    k -= 1
                else:
                    nums1[k] = nums1[i]
                    i -= 1
                    k -= 1
            if i < 0:
                while j >= 0:
                    nums1[j] = nums2[j]
                    j -= 1
            return None

题解复盘

后面看了力扣题解,发现自己的方法已经是最优解,时间复杂度$O(m+n)$,空间复杂度$O(1)$。自己后来想python是否有内存拼接的方式,将遍历结束后nums2的剩余元素一次性拼接到nums1的对应位置,这样时间复杂度能进一步降到$O(Max(m,n))$。
咨询GPT老师的结果如下:




也就是说数组的剩余元素只能逐个赋值,时间复杂度无法进一步下降。但是GPT老师对我的剩余元素赋值代码进行了优化,由遍历转为切片操作,更加简洁优雅:

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.
        """
        if n == 0:
            return None
        elif m == 0:
            for i in range(n):
                nums1[i] = nums2[i]
            return None
        else:
            i , j, k = m-1 , n-1, m+n-1
            while i >= 0  and j >= 0:
                if nums1[i] <= nums2[j]:
                    nums1[k] = nums2[j]
                    j -= 1
                    k -= 1
                else:
                    nums1[k] = nums1[i]
                    i -= 1
                    k -= 1
            if i < 0:
                # 这里以数组的切片赋值操作取代遍历元素的赋值操作
                nums1[:j+1] = nums2[:j+1]
            return None

声明:奋斗小刘|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - LeetCode 0088 合并两个有序数组


Make Everyday Count