数组训练题(合并数组和移除数组元素)

一.移除数组元素

        

        当看到这个题目时,我们首先应该会想到再创建一个数组,将原数组中的值对val进行遍历,将其得到的值转移到新数组中,但是这题对数组空间有额外的空间限制,所以我们需要另一种想法。

双变量检测

        在这里,我们可以尝试利用双变量src和dst对原数组进行检测

        假设数组里面是3223这几个数,如果我们想要删除vall = 3,我们就用

1.src和dst初始都指向初始值3

2.接下来进行检测,如果src指向val,则src++,如果src不指向val,则将arr[src]直接赋值给arr[dst],这样可以让我们需要的数据将不需要的数据直接覆盖,数组长度减少

3.这样,我们可以知道,新数组的有效长度为dst

于是,我们将思路写成代码:

int removeElement(int* nums, int numsSize, int val) {
    int src,dst;
    src = dst = 0;
    while(src < numsSize)
    {
        if(nums[src] == val)
            src++;
        else
        {
            nums[dst] = nums[src];
            src++;
            dst++;
        }

    }
    return dst;
}

这里的numsSize是原数组的总长度,这样,这题就做完了!

二.数组合并

这里,我们有两种思路,最简单的是将第二个数组直接插入第一个数组后面,再直接进行排序,但如果要进行排序,那么时间复杂度必然会较高,所以,我们使用变量检测的方法。

三变量检测

        (初始)

(末尾)

        在这里,我们定义三个变量l1,l2,l3,先将l1指向的值与l2将比较,谁的值大谁就将值放到l3,而如果从前向后比较会出现前面数据把后面数据覆盖的情况,导致数据丢失,所以这里我们选择变量从后往前移动。

两种特殊情况

        但在这里,我们还会遇到,l2已经离开循环,但l1仍然没有移动的情况,如果num1刚开始里面的值很小的话,l1将不会移动,但题目告诉我们,num1是有序的非递减数组,所以我们不用考虑这种情况。

        当l1已经离开循环,l2还没有离开时,我们可以直接循环地将num2中的值放到l1中,于是,我们将思路实现成代码:

void merge(int* nums1, int m, int* nums2, int n) {
    int l1 = m - 1;
    int l2 = n - 1;
    int l3 = m + n - 1;
    while(l1 >= 0 && l2 >= 0)
    {
        if(nums1[l1] < nums2[l2])
        {
            nums1[l3--] = nums2[l2--];
            //l3--;
            //l2--;
        }
        else 
        {
            nums1[l3--] = nums1[l1--]; 
        }
    }
    //出循环后有两种情况:l1<0或l2<0
    //只需处理l2>=0,
    while(l2 >= 0)
    {
        nums1[l3--] = nums2[l2--];
    }

    
}

这样,我们的代码就完成了!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值