采用快慢指针法来解决有关数组的问题(C语言)

文章目录

题目一

题目来源(力扣):移除元素

题目描述
给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]

这道题是移除指定值的元素。

【基本思路】
先将 slow 和 fast 都初始化为 0 。
( fast 是用来表示当前遍历到的位置的下标,slow 是用来表示要填入的位置的下标 )

当 fast 遇到要移除的元素时,跳过它(将 fast 后移一位)。
当 fast 遇到的元素不是要移除的,先将 nums[fast] 的值赋给 nums[slow],再让 slow 和 fast 都后移一位。

将上述整理成代码如下。

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

    return slow;   //最后数组的新长度是 slow
}

题目二

题目来源(力扣):删除有序数组中的重复项

题目描述
给你一个有序数组 nums ,请你原地删除重复出现的元素,使每个元素只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

示例
输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]

这道题是将重复的元素都删掉,使得不同的元素均只出现一次。

【基本思路】
先将 slow 和 fast 分别初始化为 0 和 1 。

经过分析,有以下两种情况:
情况一:如果 fast 指向位置的元素跟 slow 指向位置的元素不等,先让 slow 后移一位,再把 nums[fast] 的值赋给 nums[slow],最后让 fast 后移一位。
情况二:如果 fast 指向位置的元素跟 slow 指向位置的元素相等,说明存在重复项,只需将 fast 后移一位,重复此步骤直到遇到情况一。

( fast 是用来表示当前遍历到的位置的下标,slow 是用来表示要填入的位置的下标 )

将上述两种情况整理成代码如下。

int removeDuplicates(int* nums, int numsSize){
    if(numsSize == 0) //如果数组 nums 的长度为 0,即数组不包含任何元素,返回 0。
        return 0;

    int slow = 0, fast = 1;
    while(fast < numsSize)
    {
        if(nums[fast] != nums[slow])
        {
            ++slow;
            nums[slow] = nums[fast];
        }

        ++fast;
    }

    return slow + 1;   //最后数组的新长度是 slow + 1
}

这样操作能够保证
下标范围为 [0, slow] 的数组元素都是已经处理好的非重复项,
下标范围为 [slow + 1, fast - 1] 的数组元素都是前面数组元素的重复项。

更多文章
异或的妙用(C语言)
大数相加(C语言)
合并两个有序数组(C语言)
阶乘后的零(C语言)
调整数组顺序使奇数位于偶数前面(C语言)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值