数组中的双指针法(C语言实现)

双指针法:通过使用两个指针在一个for循环下完成两个for循环的工作

例题127. 移除元素 - 力扣(LeetCode)

题目中要求原地移除所有数值等于val的元素,也就是说我们不能使用额外的数组来存储数据,应在原数组中进行改变元素

数组的元素在内存地址中是连续的,因此我们不能直接删除某个元素,只能进行覆盖

1.暴力解法:使用两层for循环,第一层for循环遍历数组每一个元素,第二层循环用于覆盖与val相等的元素。注意在覆盖后有当前i下标所指元素依然等于val的情况,要对i进行调整再次进行覆盖

int removeElement(int* nums, int numsSize, int val) {
    
    for(int i=0;i<numsSize;i++)
    {
        if(nums[i]==val)
        {
            for(int j=i;j<numsSize-1;j++)
            {
                nums[j]=nums[j+1];
            }
            numsSize--;
        }
        if(nums[i]==val)
        {
            i--;
        }
    }
    return numsSize;
}

2.双指针法:设置两个指针初始均指向数组首元素,fast指针遍历数组中每一个元素,last指针负责覆盖元素(可以理解为last指针在创建一个新的数组)fast所指元素不等于val时,slow指针向右移动,最终遍历后slow的大小即为题中所求k的大小

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

例题2977. 有序数组的平方 - 力扣(LeetCode)

1.暴力解法:题干很简单,最暴力的方法先将数组中每个数字都进行平方,再使用排序算法处理数组,最后返回数组,该方法容易想出但时间复杂度较高,我这里写的是冒泡排序,执行用时十分长,时间复杂度为O(n+n^2),可以使用快速排序这种效率更高的算法,但整体效率都不及接下来的双指针法

int* sortedSquares(int* nums, int numsSize, int* returnSize) {
    *returnSize=numsSize;
    int* ret=(int*)malloc(sizeof(int)*numsSize);
    for(int i=0;i<numsSize;i++)
    {
        ret[i]=nums[i]*nums[i];
    }
    for(int i=0;i<numsSize;i++)
    {
        for(int j=numsSize-1;j>i;j--)
        {
            if(ret[j]<ret[j-1])
            {
                int num=ret[j-1];
                ret[j-1]=ret[j];
                ret[j]=num;
            }
        }
    }
    return ret;
}

2.双指针法:我们发现,经过平方处理后的数组中,最大值一定出现在数组的最左端或者最右端,因此我们新建一个长度与原数组相同的空数组,设置两个指针分别指向数组左右两端,比较两端大小,将数值更大的一端的元素放入空数组的末端,从后往前填充空数组,再将左指针或右指针向内移动,直到左指针在右指针右边或二者相等,终止循环,返回排序后的数组。

int* sortedSquares(int* nums, int numsSize, int* returnSize) {
    *returnSize=numsSize;
    int* ret=(int*)malloc(sizeof(int)*numsSize);
    for(int i=0;i<numsSize;i++)
    {
        ret[i]=nums[i]*nums[i];
    }
    for(int i=0;i<numsSize;i++)
    {
        for(int j=numsSize-1;j>i;j--)
        {
            if(ret[j]<ret[j-1])
            {
                int num=ret[j-1];
                ret[j-1]=ret[j];
                ret[j]=num;
            }
        }
    }
    return ret;
}

双指针法在部分题中可以提高算法效率,降低时间复杂度,其思路不难理解,但代码实现需要注意细节部分的编写,避免出现数组越界等错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值