力扣:1089. 复写零

今日分享一道力扣经典题目,复写0!

题目如下:

题目分析:

题目要求是进行复写0,而且不能超过原数组长度,且只能在原地进行操作!

解决本题最好的方法就是进行双指针方法!

算法分析

一、双指针算法先找到最后一个要复写的数

二、然后从后向前进行完成复写(因为如果要是从前向后进行复写会导致元素的覆盖!)

其中第一大步又是一个双指针的思想:再次分为了以下几步!

1.判断cur指针位置的值!

2.决定des向后移动1或2步!(如果cur的值为0则des向后移动两步,否则移动一步)!

3.判断是否达到原数组的最大长度!即(des的位置是否等于n-1)!若des已经结束,直接跳出循环!

4.若3不满足,则进行cur++操作!

5.因为最后des的位置可能是数组长度的最大值,也可能是最大值后面那个值!所以后面还需进行判断是否以及越界!若以越界,再进行修改即可!

此步骤非常重要!一定要考虑到,如若没有考虑到,那么则会导致越界的问题!

当第一大步结束时,此时des位置处于最后需要复写的最后一个位置,cur位置为最后一个复写的元素!然后最后进行从后向前完成复写即可!

画图分析:

代码实现

C代码

void duplicateZeros(int* arr, int arrSize)
{
    //双指针!解法进行求解!
    //首先先找到最后一个复写的元素!
    int cur=0;
    int des=-1;
    while(des<arrSize)
    {
        if(arr[cur])
        {
            des++;
        }
        else if(arr[cur]==0)
        {
            des+=2;
        }
        //必须需要注意的是只要des位于最后一个位置即arrSize-1即停止循环!
        if(des>=arrSize-1)
        {
            break;
        }
        cur++;
    }

    //经过此时,cur位于最后一个复写的元素!des位于最后一个位置或者之后的位置!
    //此时需要注意的是,如果des位于n的位置是,此时已经越界!
    if(des==arrSize)
    {
        arr[arrSize-1]=0;
        des-=2;
        cur--;
    }

    while(cur>=0)
    {
        if(arr[cur]==0)
        {
            arr[des--]=0;
            arr[des--]=0;
        }
        else
        {
            arr[des]=arr[cur];
            des--;
        }
        cur--;
    }
}

c++代码

class Solution {
public:
    void duplicateZeros(vector<int>& arr)
    {
        
        int cur=0;
        int des=-1;
        int n=arr.size();
        while(cur<n)
        {
            if(arr[cur])
            {
                des++;
            }
            else
            {
                des+=2;
            }
            if(des>=n-1)
            {
                break;
            }
            cur++;
        }
        if(des==n)
        {
            arr[n-1]=0;
            des-=2;
            cur--;
        }
        while(cur>=0)
        {
            if(arr[cur]==0)
            {
                arr[des--]=0;
                arr[des--]=0;
            }
            else
            {
                arr[des]=arr[cur];
                des--;
            }
            cur--;
        }
    }
};

今日分享到此结束!如若还有不懂,欢迎评论区留言!

评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值