算法小白 Leetcode刷题篇(二)

合并两个有序数组

题目指路

题目描述:
给你两个有序整数数组 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]

思路一:
直接将nums2数组中的数连接到nums1数组的后面,再对新形成的数组进行排序,可以先摸鱼一下,直接调用sort函数进行排序。

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        for(int i=0;i<n;i++){
            nums1[i+m]=nums2[i];
        }
        Arrays.sort(nums1);
    }
}

思路二:
另外再创建一个数组,使新建的数组等于nums1的前m个数字,设置两个指针p1和p2,分别指向两个数组的第一个元素,在满足循环条件的前提下,当p1指向的元素小于等于p2指向的元素时,将p1所指的元素赋值到nums1数组的对应位置上,当p1指向的元素大于p2指向的元素时,将p2所指的元素赋值到nums1数组的对应位置上,当跳出循环时,nums数组的后几位可能还没有进行赋值,此时将没有遍历完的数组部分赋值到nums1数组的后几位上。

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int p1=0;
        int p2=0;
        int count=0;
        int [] array = new int[m];
        System.arraycopy(nums1, 0, array, 0, m);
        while((p1<m)&&(p2<n)){
            if(array[p1]<=nums2[p2]){
                nums1[count]=array[p1];
                p1++;
            }else if(array[p1]>nums2[p2]){
                nums1[count]=nums2[p2];
                p2++;
            }
            count++;
        }
        if(p1<m){
            for(int i=p1;i<m;i++){
                nums1[count]=array[i];
                count++;
            }
        }
        if(p2<n){
            for(int i=p2;i<n;i++){
                nums1[count]=nums2[i];
                count++;
            }
        }
    }
}

唯一的不足就是有点占用空间。

思路三:
参考了答案之后的思路,指针从最后开始向前走,这样就可以不用另外申请一块空间保存nums1数组,可以有效地节省空间。
具体思路如下,设置三个指针,p2指向nums1数组的末尾,p2指向nums2数组的末尾,p1指向nums1有效数组的末尾(不为0的最后一位),在p3指针不断向前移动的过程中,有以下几种情况:
1.p1为-1,此时p1指针已经移动到nums1的最左端,接下来只需要将nums2数组中的剩余数字放到nums1数组中即可。
2.p2为-1,此时p2指针已经移动到nums2的最左端,接下来只需要将nums1数组中的剩余数字放到nums1数组中即可。
3.p1指针指向的数字比p2指针指向的数字大(或等于),将p1指针指向的数字移动到p3指针指向的位置,p1和p3向左移动。
4.p1指针指向的数字比p2指针指向的数字小,将p2指针指向的数字移动到p3指针指向的位置,p2和p3向左移动。

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int p1=m-1;
        int p2=n-1;
        int p3=m+n-1;
        while(p3>=0){
            if(p1==-1){
                nums1[p3]=nums2[p2];
                p3--;
                p2--;
            }else if(p2==-1){
                nums1[p3]=nums1[p1];
                p3--;
                p1--;
            }else if(nums1[p1]>=nums2[p2]){
                nums1[p3]=nums1[p1];
                p3--;
                p1--;
            }else if(nums1[p1]<nums2[p2]){
                nums1[p3]=nums2[p2];
                p3--;
                p2--;
            }
        }
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值