leetcode学习记录
leetcode学习记录七
合并有序数组
难度:简单
给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
输出: [1,2,2,3,5,6]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
1.从头开始有两个数组两个指针p、q,指向要比较的元素,还有一个数组作为目标数值向内插入数值,有一指针i
2.先将数组合并在进行排序,代码量少,但时间复杂度较高 (没想到的做法)
3.指针从尾开始,用两数组用p,q指向最后一个元素,找最大的插入,从nums1的尾部开始插入,本题最适合的方法,不需要再声明一个数组,时间复杂度O(m+n),空间复杂度O(1) (没想到的做法)
代码
//方法一 我自己的实现方法,代码不咋优美
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int p = 0 , q = 0 , i = 0;
int[] temp = new int[m+n];
while((p < m) && (q < n)){
if(nums1[p] <= nums2[q]){
temp[i++] = nums1[p++];
}
else{
temp[i++] = nums2[q++];
}
}
//arraycopy(arr1,p,arr2,q,num);arr1为要复制的数组,p为复制的初始位置,arr2为要复制到的目标数组,q为初始位置,num为复制的个数
if (p < m)
System.arraycopy(nums1, p, temp, i, m - p);
if (q < n)
System.arraycopy(nums2, q, temp, i, n - q);
System.arraycopy(temp, 0, nums1, 0, m+n);
}
}
//方法一 题解的代码,代码比上面的简洁,思路一样,空间复杂度稍微低一些
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);
}
}
//方法二 合并数组再排序
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
System.arraycopy(nums2, 0, nums1, m, n);
Arrays.sort(nums1);
}
}
//方法三
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);
}
}
总结
1.有从尾开始的意识,前面一些题也有一些从尾开始或首位一起开始的做法,可能会更加简单;
2.条件 ? 表达式1 : 表达式2,这个式子可使代码更加简洁
3.arraycopy(arr1,p,arr2,q,num);arr1为要复制的数组,p为复制的初始位置,arr2为要复制到的目标数组,q为初始位置,num为复制的个数