leetcode 88. Merge Sorted Array 详解 python3

一.问题描述

Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.

Note:

  • The number of elements initialized in nums1 and nums2 are m and n respectively.
  • You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2.

Example:

Input:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6],       n = 3

Output: [1,2,2,3,5,6]

二.解题思路

题目本身不难,但是要求in_place操作,

如果要求常数内存O(1),就稍微复杂一点。

介绍俩O(1)内存方法。

方法一:

考虑如果我们可以新开内存怎么做?

我们新开一个数组(大小m+n),然后比较nums1第一个元素和nums2第一个元素谁小,谁更小就丢新开的数组里面,然后继续比较。

然而问题是不开新内存,注意题目说的nums1大小至少m+n,就会想是否可以这样用?

但是nums1本身的元素已经占在前面了,我们不能用,既然后面可以用,何不反其道而行?

对于上面假设不要求常数内存的例子,我们也可以比较nums1和nums2的最后一个元素,谁大就放在新开内存的最后面,慢慢迭代。

这样子我们就可以利用本题nums1的特性,把数丢后面,也不会影响nums1本身的数。

有人可能会问是否会影响nums1本身的数?

思考什么时候会影响nums1本身的数,假设nums1[i]被影响,影响是指nums1[i]这个数还没被拿去比较,就已经被nums2某个数占了,这说明nums2的大小至少得需要m+n-i+1(假设nums1[i]~nums[m+n-1]全被nums2的数占了,虽然可能有部分被nums1本身值占用,但是这部分不影响)。i最大是m,所以nums2的大小至少是m+n-m+1=n+1,然而nums2大小是n,因此不可能。

nums1[i]不可能会被nums1本身的数给影响。因为nums1的数被移动末尾,并不影响nums1的值在nums1所占的空间大小。

比如说nums1[10]被移动到nums1[100],虽然占用了第100个位置,但是释放了第10个位置。所以不会影响nums1的10之前数的数的处理。只有nums2的数加进nums1才可能就影响nums2本身的值,因为占用了新的空间。

时间复杂度O(m+n-1),空间复杂度O(1)

方法二:

死方法,从左开始处理。

比较两个数组的开头,nums2的数小,就插进nums1里面,然后将nums1之后的值全部右移1格。

小小的一个优化就是,不要出现一个nums2的值小于nums1的值就插入一次,判断nums2连续的几个值是不是都小于nums1的那个值,如果是的话就一次性插入nums2这几个小于的值进nums1,毕竟插入操作很花时间。

详细见代码。

时间复杂度O(m*m),空间复杂度O(1);

更多leetcode算法题解法: 专栏 leetcode算法从零到结束  或者 leetcode 解题目录 Python3 一步一步持续更新~

三.源码

方法一

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.
        """
        # 18
        total_len=m+n-1
        for i in range(total_len,-1,-1):
            if n<1:break
            if m<1:
                nums1[:n]=nums2[:n]
                break
            if nums1[m-1]>nums2[n-1]:
                nums1[i]=nums1[m-1]
                m-=1
            else:
                nums1[i]=nums2[n-1]
                n-=1
                
            

方法二:

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.
        """
        # 18
        i,j=0,0
        len_nums1=len(nums1)
        while i<m:
            jstart=j
            while j<n:
                if nums2[j]<nums1[i]:j+=1
                else: break
            nums1[i+j-jstart:]=nums1[i:len_nums1-j+jstart]
            nums1[i:i+j-jstart]=nums2[jstart:j]
            m+=j-jstart
            i+=1
        nums1[m:m+n-j]=nums2[j:]
发布了218 篇原创文章 · 获赞 191 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/CSerwangjun/article/details/103428431