【LeetCode刷题】88. 合并两个有序数组

1:题目描述

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

请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

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

2:解题方法

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

合并两个有序数组,可以想到归并排序。归并排序是把两个有序的数组合并,放到另外一个数组中。空间复杂度是O(M+N)的。

因为最终的结果是要按非递减顺序排序,因此需要比较nums1[0:m]和nums2[0:n]中数字的大小。

有两种思路:

        思路一:如果两个数组从开头向结尾(数字从小到大)进行比较,那么每次比较之后的数字放到nums1中的前面,则需要把nums1中第k个位置(与nums2中进行比较的位置)后面的元素向后移动,这样移动次数较多。

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

显然思路二更好。

从后向前进行比较

1:当m>0并且n>0时,从后向前比较nums1[m-1]和muns2[n-1]:

如果是nums1[m-1]大,则把nums1[m-1]放到nums1中的m+n-1的位置,并让m-=1,

如果是nums2[n-1]大,则把nums2[n-1]放到nums1中的m+n-1的位置,并让n-=1。

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

当m==0时,说明nums1中的数字已经遍历完了,此时nums2中可能还剩元素,需要把nums2中还剩余的元素复制到nums1的头部,

当n==0时,说明nums2中的数字已经遍历完了,此时nums1中可能还剩元素,由于剩余的元素一定是nums1和nums2中最小的元素,所以不用移动位置,直接留在原地就行。

以nums1 = [2,3,5,0,0],m = 3,nums2 = [1,6],n = 0为例,绿色是正在比较的元素,红色是刚刚放置过的元素。

具体思路展示:

【LeetCode刷题】88. 合并两个有序数组_第1张图片

 

 【LeetCode刷题】88. 合并两个有序数组_第2张图片

 【LeetCode刷题】88. 合并两个有序数组_第3张图片

 【LeetCode刷题】88. 合并两个有序数组_第4张图片

 【LeetCode刷题】88. 合并两个有序数组_第5张图片

 【LeetCode刷题】88. 合并两个有序数组_第6张图片

 【LeetCode刷题】88. 合并两个有序数组_第7张图片

 【LeetCode刷题】88. 合并两个有序数组_第8张图片

 【LeetCode刷题】88. 合并两个有序数组_第9张图片

 【LeetCode刷题】88. 合并两个有序数组_第10张图片

 代码展示:

class Solution:
    def merge(self, nums1, m, nums2, n):
        k = m+n-1  #数组nums1最后一个元素的位置
        while m>0 and n>0:
            if nums1[m-1]>nums2[n-1]:
                nums1[k] = nums1[m-1]
                m -= 1
            else:
                nums1[k] = nums2[n-1]
                n -= 1
            k -= 1
        # 当m!=0,n=0,说明nums2已经遍历完了,nums1还有剩余,因为剩余的元素本身就是最小的,所以不用挪动位置
        # 当m=0,n!=0,说明nums1已经遍历完了,nums2还有剩余,并且nums2剩余的都比nums1最小的还小,所以直接放到最前面
        nums1[:n] = nums2[:n]
        return nums1

if __name__ == '__main__':
    nums1 = [2,3,5,0,0]
    m = 3
    nums2 = [1,6]
    n = 2
    print(Solution().merge(nums1,m,nums2,n))

你可能感兴趣的:(Leetcode,leetcode,python)