题设:
两个递增数列nums1,nums2;
nums1有效元素个数m,nums2有效元素个数n,长度n;
nums1长度为m+n,空缺部分用0补齐;
合并两个数列至nums1,使其成为递增数列;
解法:
1.调用Arrays.sort
思路:把nums2元素填充到nums1空位上,然后调用Arrays.sort对nums1排序
class Solution{
public void merge(int[] nums1,int m,int[] nums2,int n) {
//将nums2的值赋给nums1
for(int i=m,j=0;i<nums1.length;i++,j++){
nums1[i]=nums2[j];
}
//排序//右中括号外的内容与上行右中括号对齐
Arrays.sort(nums1);
}
}
评析:
Arrays.sort的原理是快速排序,根据传入元素数量,此方法的时间复杂度是O(m+n)log(m+n)。
代码简单,但执行效率不高,因为这个过程是有序+有序—>无序—>有序,两个数组本身的有序性未利用起来。
2.创建临时数组,双指针
思路:对比两数组首位大小得到最小值,将该值放到临时数组第一位,以此类推。最后将临时数组内容拷贝到nums1。
class Solution{
public void merge(int[] nums1,int m,int[] nums2,int n){
//创建临时数组
int[] temp=new int[m+n];
//开始对比和填数,准备3个指针index,n1Index,n2Index分别指向3个数组
for(int index=0,n1Index=0,n2Index=0;index<m+n;index++){
//4种情况
//n1取完.n2赋给temp,n2Index++
if(n1Index>=m){
temp[index]=nums2[n2Index];
n2Index++;
}//反括号与所属结构开头对齐
//n2取完,n1赋给temp,n1脚标自增
else if(n2Index>=n){
temp[index]=nums1[n1Index];
n1Index++;
}
else if(nums1[n1Index]>nums2[n2Index]){
temp[index]=nums2[n2Index];
n2Index++;
}
else{
temp[index]=nums1[n1Index];
n1Index++;
}
}
for(int i=0;i<temp.length;i++){
nums1[i]=temp[i];
}
}
}
评析:
两个数组各循环一遍,时间复杂度O(m+n)
额外产生临时数组的大小为m+n,空间复杂度也是O(m+n)
nums1的剩余空间未充分利用
*衡量时间复杂度,算传入元素数量
衡量空间复杂度,算额外占据空间大小
3.不额外创建数组
思路:比较尾数得到最大值,直接放入nums1末尾,不创建临时数组
class Solution{
public void merge(int[] nums1,int m,int[] nums2,int n){
//直接比较大小,准备3个指针分别指向n1,n2,完成排序的n1
for(int index=m+n-1,n1Index=m-1,n2Index=n-1;index>=0;index--){
//如果n1取完,则把n2赋给nums1
if(n1Index<0){
nums1[index]=nums2[n2Index];
n2Index--;
}
else if(n2Index<0){
nums1[index]=nums1[n1Index];
n1Index--;
}
else if(nums1[n1Index]>nums2[n2Index]){
nums1[index]=nums1[n1Index];
n1Index--;
}
else{
nums1[index]=nums2[n2Index];
n2Index--;
}
}
}
}
评析:
充分利用nums1和nums2的有序性,以及nums1的剩余空间
未引入额外数组,空间复杂度O(1)
两数组各循环一次,时间复杂度O(m+n)
声明:内容学习自b站视频"【比刷剧还爽!】13天高效刷题 | 哔哩最强LeetCode算法刷题...",感谢up,获益良多。文字全部是个人学习总结,代码为个人默打,如有侵权,请联系后处理。