LeeCode 88 ——合并两个有序数组

 题目:

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。

请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

示例 1:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。

解法一:数组+排序

思路:

因为nums1有足够的空间来存放nums2,所以可以将nums2中的数据,全部存放在nums1中,然后在进行排序;

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        System.arraycopy(nums2,0,nums1,m,n);
        Arrays.sort(nums1);
    }
}

 复杂度分析:1、时间复杂度:O((n+m)*log(n+m))

                        2、空间复杂度:O(1)

扩:System.arraycopy()函数的使用 

 基本定义:

public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

src:源数组;

srcPos:源数组要复制的起始位置;

dest:目的数组;

destPos:目的数组放置的起始位置;

length:复制的长度.
 

例如:System.arraycopy(nums2,0,nums1,m,n);

解释为:在nums2中,从其下标为0的数据开始,取n个数据,放在nums1中下标为m的位置处;

注意:

这里要数组放入的数据的个数是不能超过它本身的长度的,否则会报数组异常错误。

此功能要求:  1、源的起始位置+长度不能超过末尾
                        2、目标起始位置+长度不能超过末尾
                        3、 所有的参数不能为负数

Array.sort()函数:

表示将括号里的数组,从小到大进行升序排序

———————————————————————————————————————————

解法二:双指针/(从前往后)

思路:

定义两个指针,复制数组1,并将两个数组的数据依次进行遍历比较,相对小的数据,存放在指定nums1数组中;

…………

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int[]nums1_coy= new int[m];
        System.arraycopy(nums1,0,nums1_coy,0,m);
        //使用上面提到的arraycopy函数,对nums1进行赋值

        int p=0,p1=0,p2=0;
        while((p1<m) && (p2< n))
            nums1[p++]=nums1_coy[p1]<nums2[p2] ? nums1_coy[p1++]  : nums2[p2++];
        //比较两个指针p1和p2,相对小的数据,放在nums1,直至所有数据都比较完毕;
        
        if(p1<m)
            System.arraycopy(nums1_coy,p1,nums1,p1+p2,m+n-p1-p2);
        if(p2<n)
            System.arraycopy(nums2,p2,nums1,p1+p2,m+n-p1-p2);
    }
}

复杂度分析:1、时间复杂度:O(n+m) 

                        2、空间复杂度:O(m)

_____________________________________________________________________________

解法三:双指针/(从后往前)倒序法

思路:

和解法二类似,但是解法二需要重新复制一个nums1,增加了算法的空间复杂度,解法三在此基础上对其进行优化;

从后往前进行比较,指针p1和p2进行比较,较大的那个数据放在nums1后面(nums1中,有足够的空间来存放nums2),然后移动较大的那个指针,依次遍历比较,直到指针指向负数,即比较完全部的数据。

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {

        int p1=m-1;
        int p2=n-1;
        //p1和p2皆指向数组最后的一个数据

        int p=m+n-1;

        while((p1>=0) && (p2>=0))
            nums1[p--]=nums1[p1]<nums2[p2] ?  nums2[p2--] :nums1[p1--] ;
            System.arraycopy(nums2,0,nums1,0,p2+1);
        }
}

复杂度分析:1、时间复杂度:O(n+m) 

                        2、空间复杂度:O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LeetCode是一个在线的编程题库,提供了各种各样的算法数据结构问题供开发者练习和提高编程能力。其中,提到了三个与数组相关的问题。 第一个引用是关于合并两个有序数组的问题,即将两个有序的整数数组合并成一个有序数组。具体的解法可以使用双指针法,分别指向两个数组的末尾,然后比较两个指针指向的元素大小,将较大的元素放入结果数组的末尾,然后将指针向前移动。这个过程重复直到其中一个数组遍历完毕,然后将剩下的元素依次放入结果数组中。 第二个引用是关于移除元素的问题,即移除数组中指定的元素,并返回新数组的长度。可以使用双指针法,左指针维护非指定元素的末尾位置,右指针遍历数组。当右指针指向的元素不等于指定元素时,将右指针指向的元素赋值给左指针指向的位置,然后将左指针和右指针都向前移动一位。直到右指针遍历完整个数组,最后返回左指针的值,即为新数组的长度。 第三个引用也是关于移动零元素的问题,即将数组中的零元素移动到数组末尾,同时保持非零元素的相对顺序不变。可以使用双指针法,左指针维护非零元素的末尾位置,右指针遍历数组。当右指针指向的元素不等于零时,将右指针指向的元素与左指针指向的元素交换位置,然后将左指针和右指针都向前移动一位。直到右指针遍历完整个数组,即完成了零元素的移动。 这些问题都可以使用双指针法解决,利用双指针在数组上进行遍历和操作,实现对数组的操作和处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [LeeCode每日一题–合并两个有序数组](https://download.csdn.net/download/weixin_38645669/14856034)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [LeeCode 数组题目](https://blog.csdn.net/weixin_43763903/article/details/114675786)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值