您好,登录后才能下订单哦!
# LeetCode中如何合并两个有序数组
## 问题描述
LeetCode第88题"合并两个有序数组"(Merge Sorted Array)是算法学习中的经典问题。题目要求如下:
给定两个按非递减顺序排列的整数数组`nums1`和`nums2`,以及两个整数`m`和`n`,分别表示`nums1`和`nums2`中的元素数目。要求将`nums2`合并到`nums1`中,使合并后的数组同样按非递减顺序排列。
注意:
- `nums1`的长度为`m + n`,其中前`m`个元素表示应合并的元素,后`n`个元素为0,应被忽略
- `nums2`的长度为`n`
示例:
```python
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
最直观的方法是直接将nums2
放入nums1
的尾部,然后对整个数组进行排序。
def merge(nums1, m, nums2, n):
nums1[m:] = nums2
nums1.sort()
时间复杂度:O((m+n)log(m+n))
空间复杂度:O(1)
虽然简单,但这种方法没有利用数组已有序的特性,效率不高。
利用两个指针分别指向nums1
和nums2
的开头,比较两个指针所指元素,将较小的放入新数组。
def merge(nums1, m, nums2, n):
sorted = []
p1, p2 = 0, 0
while p1 < m or p2 < n:
if p1 == m:
sorted.append(nums2[p2])
p2 += 1
elif p2 == n:
sorted.append(nums1[p1])
p1 += 1
elif nums1[p1] < nums2[p2]:
sorted.append(nums1[p1])
p1 += 1
else:
sorted.append(nums2[p2])
p2 += 1
nums1[:] = sorted
时间复杂度:O(m+n)
空间复杂度:O(m+n)
这种方法需要额外的空间存储排序结果,不符合题目要求的原地修改。
从两个数组的末尾开始比较,将较大的元素放入nums1
的末尾。这种方法避免了额外的空间开销。
def merge(nums1, m, nums2, n):
p1, p2, p = m-1, n-1, m+n-1
while p1 >= 0 and p2 >= 0:
if nums1[p1] > nums2[p2]:
nums1[p] = nums1[p1]
p1 -= 1
else:
nums1[p] = nums2[p2]
p2 -= 1
p -= 1
nums1[:p2+1] = nums2[:p2+1]
时间复杂度:O(m+n)
空间复杂度:O(1)
以最优的逆向双指针法为例,详细解析实现过程:
初始化指针:
p1
指向nums1
的最后一个有效元素(索引m-1
)p2
指向nums2
的最后一个元素(索引n-1
)p
指向nums1
的末尾(索引m+n-1
)比较和填充:
nums1[p1]
和nums2[p2]
,将较大的值放入nums1[p]
处理剩余元素:
nums2
还有剩余元素(p2 >= 0
),直接复制到nums1
开头方法 | 时间复杂度 | 空间复杂度 |
---|---|---|
直接排序 | O((m+n)log(m+n)) | O(1) |
双指针(正向) | O(m+n) | O(m+n) |
双指针(逆向) | O(m+n) | O(1) |
合并有序数组的思想广泛应用于: 1. 数据库的归并排序 2. 大数据处理中的外排序 3. 分布式系统中的有序结果合并 4. 版本控制系统中的变更合并
合并两个有序数组问题展示了如何利用双指针技巧高效处理有序数据。逆向双指针法通过从后向前填充,实现了O(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.
"""
p1, p2 = m-1, n-1
for p in range(m+n-1, -1, -1):
if p2 < 0:
break
if p1 >= 0 and nums1[p1] > nums2[p2]:
nums1[p] = nums1[p1]
p1 -= 1
else:
nums1[p] = nums2[p2]
p2 -= 1
通过这些问题可以进一步加深对合并算法的理解。 “`
注:本文约1500字,详细介绍了LeetCode合并两个有序数组问题的多种解法,重点分析了最优解决方案的实现细节和复杂度,并提供了相关扩展思考。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。