[LeetCode][C++] 合并两个有序数组

合并两个有序数组

给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。

说明:
初始化 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]


思路:

  1. 特殊情况,num1序列为空,此时直接将num2赋值给num1。
  2. 通常情况,遍历num2序列,将其中的元素一个个插入到num1。
    \quad - 先和num1的最后一个元素比较,判断是否在num1末尾插入。
    \quad - 和其他元素比较,找到插入位置,并记录插入位置
  3. 由于该题的数据格式原因,我们每次插入一个元素到num1,要更新num1中的有效元素个数,即m++,不能直接调用num1.size()。最后,我们需要删除num1末尾的0。

代码:
需要注意vector的insert()方法:

//在位置为m的元素前插入元素to_insert
//插入后,m的位置存储元素to_insert 
vector<int> nums;
nums.insert(nums.begin()+m,to_insert);  

函数整体代码如下:
方法一:从后面开始插入

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int l=m-1,r=n-1, to_insert=m+n-1;
        while(l>=0 && r>=0)
        {
            if(nums1[l]>=nums2[r])
            {
                nums1[to_insert--]=nums1[l--]; 
            }else{
                nums1[to_insert--]=nums2[r--]; 
            }
        }
        while(l>=0)
                nums1[to_insert--]=nums1[l--];
        while(r>=0)
                nums1[to_insert--]=nums2[r--];
        
    }
};

麻烦的方法二:

void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int cur_ind=0, j=0;
        //nums1为空
        if(m==0)
        {
            nums1=nums2;
        }else
        { //通常情况            
            for(int i=0;i<n;i++)   
            {
                int to_insert=nums2[i];
                //先和最后一个元素比较
                if(to_insert>=nums1[m-1])   
                {
                    nums1.insert(nums1.begin()+m,to_insert);   //末尾插入元素
                    m++;     //更新nums1元素个数
                    continue;
                }
                //和其他元素比较,找到插入位置
                for(j=cur_ind;j<m-1;j++)  
                {
                    int to_compare_left=nums1[j];
                    int to_compare_right=nums1[j+1];
                    if(to_insert >= to_compare_left && to_insert < to_compare_right )
                    {
                        cur_ind=j+1;
                    }
                }
                //插入
                nums1.insert(nums1.begin()+cur_ind,to_insert);  //在cur_ind前插入元素,插入后,cur_ind指向插入元素     
                m++;   //更新nums1元素个数
            }
            //删除nums1结尾的0
            for(int i=0;i<n;i++)
            {
                nums1.erase(nums1.end()-1);
            }
        }       
    }

简化代码:

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
		if (m == 0)
    	{
        	nums1 = nums2;
        	return ;
    	}
		
		int cur = 0;
		for (int i = 0; i < n; i++)
			nums1.pop_back();
		for (int i = 0; i < n; i++)
		{
			if (nums2[i] >= nums1[m - 1])
			{
				for (int j = i; j < n; j++)
				{
					nums1.push_back(nums2[j]);
					m++;
				}
				break;
			}
			while (nums2[i] >= nums1[cur])
			{
				cur++;
			}
			nums1.insert(nums1.begin() + cur, nums2[i]);
			cur++;
			m++;
		}
	}
};

结果:
合并两个有序数组

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值