解法一:合并后排序
最朴素的解法就是将两个数组合并之后再排序。该算法只需要一行(Java是2行),时间复杂度较差,为O((n+m)log(n+m))。这是由于这种方法没有利用两个数组本身已经有序这一点。
java版本
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
System.arraycopy(nums2, 0, nums1, m, n); //拷贝nums2数组中0到n数据,到nums1
Arrays.sort(nums1);
}
}
关于System.arraycopy用法
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
代码解释:
Object src : 原数组
int srcPos : 从元数据的起始位置开始
Object dest : 目标数组
int destPos : 目标数组的开始起始位置
int length : 要copy的数组的长度
https://blog.csdn.net/qq_32405269/article/details/78374035
python版本
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: void Do not return anything, modify nums1 in-place instead.
"""
nums1[:] = sorted(nums1[:m] + nums2)
python区别nums = A和nums[:] = A
nums = A 更改nums这一变量名所指的对象,让nums变量指向A所指向的对象
nums[:] = A 对nums指向的对象赋值,把A变量指向的对象的值逐个复制到nums指向的对象中并覆盖nums指向的对象的原来值。
nums[:] 等价于 nums[0:len(nums)] 相当于取nums对应对象的一个视图,通过用这个来改变原对象的某几位值。
如:A[:2] = [0, 1],改变了A所指向的list对象的前两个值。
A = [0 ,1],让A这一变量名指向新的List对象[0,1]
复杂度分析
时间复杂度 : O((n + m)\log(n + m))。
空间复杂度 : O(1)。
解法二:双指针/从前往后
python版本
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: void Do not return anything, modify nums1 in-place instead.
"""
# Make a copy of nums1.
nums1_copy = nums1[:m]
nums1[:] = []
# Two get pointers for nums1_copy and nums2.
p1 = 0
p2 = 0
# Compare elements from nums1_copy and nums2
# and add the smallest one into nums1.
while p1 < m and p2 < n:
if nums1_copy[p1] < nums2[p2]:
nums1.append(nums1_copy[p1])
p1 += 1
else:
nums1.append(nums2[p2])
p2 += 1
# if there are still elements to add
if p1 < m:
nums1[p1 + p2:] = nums1_copy[p1:]
if p2 < n:
nums1[p1 + p2:] = nums2[p2:]
java版本
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
// Make a copy of nums1.
int [] nums1_copy = new int[m];
System.arraycopy(nums1, 0, nums1_copy, 0, m);
// Two get pointers for nums1_copy and nums2.
int p1 = 0;
int p2 = 0;
// Set pointer for nums1
int p = 0;
// Compare elements from nums1_copy and nums2
// and add the smallest one into nums1.
while ((p1 < m) && (p2 < n))
nums1[p++] = (nums1_copy[p1] < nums2[p2]) ? nums1_copy[p1++] : nums2[p2++];
// if there are still elements to add
if (p1 < m)
System.arraycopy(nums1_copy, p1, nums1, p1 + p2, m + n - p1 - p2);
if (p2 < n)
System.arraycopy(nums2, p2, nums1, p1 + p2, m + n - p1 - p2);
}
}
复杂度分析
时间复杂度 : O(n + m)。
空间复杂度 : O(m)。
解法三:双指针/从后往前
python版本
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: void Do not return anything, modify nums1 in-place instead.
"""
# two get pointers for nums1 and nums2
p1 = m - 1
p2 = n - 1
# set pointer for nums1
p = m + n - 1
# while there are still elements to compare
while p1 >= 0 and p2 >= 0:
if nums1[p1] < nums2[p2]:
nums1[p] = nums2[p2]
p2 -= 1
else:
nums1[p] = nums1[p1]
p1 -= 1
p -= 1
# add missing elements from nums2
nums1[:p2 + 1] = nums2[:p2 + 1]
java版本
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
// two get pointers for nums1 and nums2
int p1 = m - 1;
int p2 = n - 1;
// set pointer for nums1
int p = m + n - 1;
// while there are still elements to compare
while ((p1 >= 0) && (p2 >= 0))
// compare two elements from nums1 and nums2
// and add the largest one in nums1
nums1[p--] = (nums1[p1] < nums2[p2]) ? nums2[p2--] : nums1[p1--];
// add missing elements from nums2
System.arraycopy(nums2, 0, nums1, 0, p2 + 1);
}
}
复杂度分析
时间复杂度 : O(n + m)。
空间复杂度 : O(1)。
参考链接https://leetcode-cn.com/problems/merge-sorted-array/solution/he-bing-liang-ge-you-xu-shu-zu-by-leetcode/