- 掘金团队号上线,助你 Offer 临门! 点击 查看活动详情
本题核心
每天一道简单算法,防止老年痴呆~
题目描述
给你两个有序整数数组 nums1
和 nums2
,请你将 nums2
合并到 nums1
中,使 nums1
成为一个有序数组。
初始化 nums1
和 nums2
的元素数量分别为 m
和 n
。你可以假设 nums1
的空间大小等于 m + n
,这样它就有足够的空间保存来自 nums2
的元素。
示例 1:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
示例 2:
输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]
提示:
nums1.length == m + n
nums2.length == n
0 <= m, n <= 200
1 <= m + n <= 200
-109 <= nums1[i], nums2[i] <= 109
复制代码
解题思路
最简单方法,遍历nums1数组,然后往里插入nums2数组的值。
双指针: 根据题目提示nums1和nums2是两个已排序的数组,那么可以利用这个用双指针实现O(m+n)时间复杂度,O(m+n)空间复杂度的算法。
反向双指针:题目中还提示给出nums1后半部分的n长度都是空的,那么可以双指针倒序进行比较插值。实现
O(1)的空间复杂度。
解题代码
暴力简单解
public void merge(int[] nums1, int m, int[] nums2, int n) {
for(int i=0;i<m+n;i++){
if(i>=m){
nums1[i]=nums2[i-m];
}
}
Arrays.sort(nums1);
}
复制代码
双指针
public void merge(int[] nums1, int m, int[] nums2, int n) {
int p1 = 0, p2 = 0;
int[] sorted = new int[m + n];
int cur;
while (p1 < m || p2 < n) {
if (p1 == m) {//如果p1==m说明左边插完了。接着插nums2
cur = nums2[p2];
p2++;
} else if (p2 == n) {如果p2==n说明右边插完了。接着插nums1
cur = nums1[p1];
p1++;
} else if (nums1[p1] < nums2[p2]) {
//先从nums1[0]和nums2[0]比较开始
//如果左边小于右边,则p1自增
cur = nums1[p1];//并把此时p1的值插入到sorted数组里
p1++;
} else {//反之则把p2的值插入到sorted数组里
cur = nums2[p2];
p2++;
}
sorted[p1 + p2 - 1] = cur;
}
for (int i = 0; i != m + n; ++i) {
nums1[i] = sorted[i];
}
}
复制代码
反向双指针
public void merge(int[] nums1, int m, int[] nums2, int n) {
int p1 = m - 1, p2 = n - 1;//左指针在nums1最后一位,右指针在nums2最后一位
int tail = m + n - 1;//倒序开始下标为m+n-1
int cur;
while (p1 >= 0 || p2 >= 0) {//p1 p2小于0则已经遍历完了
if (p1 == -1) {
cur = nums2[p2];
p2--;
} else if (p2 == -1) {
cur = nums1[p1];
p1--;
} else if (nums1[p1] > nums2[p2]) {//对比nums1和nums2最右边的数的大小
cur = nums1[p1];//nums1比nums2的最右边更大则把最大值存在cur里
p1--;//p1指针向左移
} else {
cur = nums2[p2];//反之p2向左移
p2--;
}
nums1[tail] = cur;//赋值到nums1的右边value=0的位置
tail--;
}
}
复制代码
##总结
简单算法,对于防止老年痴呆,非常好用?
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END