好记性不如烂笔头----数组练习题

1.第一题(移除元素)

先将第一题的链接附上

https://leetcode.cn/problems/remove-element/description/

拿到题我们先分析,首先不能使用额外的数组空间,那就是只能在原数组上操作;

其次元素顺序可以改变,说明我们不用考虑排序的问题,加上只能原地修改数组我们可以考虑使用双指针,然后画图分析(很关键)。

  1.  首先创建两个指针 src  dst
  2. 然后思考其运行条件,当src走到数组最后一个时结束
  3. nums[src] != val时将nums[src] 的值传给nums[dst](nums[dst]==nums[src]),dst++,src++
  4. nums[src] == valsrc++,dst不动
  5. 返回dst就是返回到新的数组长度。

完整代码如下:

int removeElement(int* nums, int numsSize, int val) {
    int src = 0;
    int dst = 0;
    //当src小于数组的最后一个下标时运行
    while (src < numsSize)
    {
        //当src所指向的值不等于val时,将src所指向的值传给dst
        if (nums[src] != val)
        {
            nums[dst] = nums[src];
            dst++;
            src++;
        }
        //当src所指向的值等于val时,src++向后移动继续寻找
        else
        {
            src++;
        }
    }

    //返回数组新长度
    return dst;

}

2.第二题

26. 删除有序数组中的重复项 - 力扣(LeetCode)

 分析:

  1. 依然可以使用两个指针 fast slow 通过错位比较完成
  2. nums[fast]指向数组外时结束
  3. 当fast所指向的值不等于slow所指向的值时,先++指向下一个位置再将fast的值传给slow,slow++,fast++

  4.  然后 return slow + 1

完整代码如下:

int removeDuplicates(int* nums, int numsSize){
    int slow = 0;
    int fast = 1;
    //当fast指向数组外时结束
    while(fast < numsSize){
        //当fast所指向的值不等于slow所指向的值时,先++指向下一个位置再将fast的值传给slow,slow++,fast++
        if(nums[fast] != nums[slow])
        {
            slow++;
            nums[slow] = nums[fast];
            fast++;
        }
        else
        {
            fast++;
        }
        
    }
    return slow + 1;
}

3.第三题

88. 合并两个有序数组 - 力扣(LeetCode)

 分析:

通过分析题目可知,我们可以使用暴破,双指针+额外存储空间来完成该题,但是这两种做法的空间和时间复杂度至少都是 O(m+n)。我们可以考虑 原地修改 ,将空间复杂度降低到 O(1)。

因为这样不需要使用额外的数组空间了,我们完全可以把 nums2 也放入 nums1中。

原地修改时,为了避免从前往后遍历导致原有数组元素被破坏掉,我们要选择从后往前遍历!

所以,我们总共需要创建三个指针,两个指针用于指向 nums1 和 nums2的初始化元素数量的末位,也就是分别指向 m−1 和 n−1的位置,还有一个指针,我们指向 nums1 数组末位即可。

依次比较取大的尾插。

 完整代码:

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    int end1=m-1;
    int end2=n-1;
    int end=m+n-1;
    
    while(end1>=0&&end2>=0)
    {
        if(nums1[end1]>nums2[end2])
        {
            nums1[end]=nums1[end1];
            end--;
            end1--;
        }
        else
        {
            nums1[end]=nums2[end2];
            end--;
            end2--;
        }
    }

    while(end2>=0)
    {
        nums1[end]=nums2[end2];
        end--;
        end2--;
    }

}

以上就是我对这些题的思路解法,如有不对不妥之处,有更好的思路的欢迎大家在评论区交流。

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王朵拉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值