【算法专题】双指针算法之 1089.复写零(力扣)

欢迎来到 CILMY23的博客

🏆本篇主题为:双指针算法之 1089.复写零(力扣)

🏆个人主页:CILMY23-CSDN博客

🏆系列专栏:Python | C++ | C语言 | 数据结构与算法 | 贪心算法 | Linux | 算法专题 | 代码训练营

🏆感谢观看,支持的可以给个一键三连,点赞关注+收藏。


✨写在前头: 

1089. 复写零 - 力扣(LeetCode)


题目

给你一个长度固定的整数数组 arr ,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。

注意:请不要在超过该数组长度的位置写入元素。请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。

一、题目解析

 通过题目我们可知:

  1. 整数数组 arr 是长度固定的
  2. 该数组中出现的每个零都复写一遍,并将其余的元素向右平移。
  3. 不要在超过该数组长度的位置写入元素
  4. 就地修改
  5. 不返回任何东西

二、算法原理

 暴力解法

 我的想法是这样的,假设有个i指向数组的左边,假设有个j指向数组的右边。

我先每次都让i往右走,直到i找到0

然后我开始从j位置,每次都让前面的位置向后移动。 

 

直到 j == i的时候,让这个位置的数,添加0,就算复写0了。

然后这个时候i就不可以++了,而是加2.

然后j再从右边开始。 

双指针算法 

其实我的想法好像相差无几,这是一个从后向前的同向双指针 

 第一步:找到最后一个“复写”的数

定义两个指针,一个是cur 指向数组最左边,一个是dest 指向-1,当 cur 所指向的位置不为0时,dest前进1,当cur 指向0时候,这时候dest就要前进2步。 

遍历完后: 

特殊情况:

dest可能越界:

 如何处理?

也就是在越界的地方我们并不修改,对n-1的地方进行修改为0,然后cur前进一步,dest 前进两步。

第二步:

然后进行复写操作 即可,当cur指向不为0的时候,dest拷贝一个,cur指向0的时候,拷贝一个0.

三、代码编写

暴力解法:

class Solution {
public:
    void duplicateZeros(vector<int>& arr) 
    {
        int n = arr.size() - 1;
        int i = 0;
        int j = n;
        while(i <= n)
        {
            if(arr[i]!=0) //找0
            {
                i++;
            }
            else
            {
                j = n; //每次j都要从右边开始
                while(i < j)
                {
                    arr[j] = arr[j -1];
                    j--;
                }
                arr[i] = 0;
                i += 2;
            }
        }
    }
};

 双指针算法:

class Solution {
public:
    void duplicateZeros(vector<int>& arr) 
    {
        // 1. 找到最后一个复写的数
        int cur = 0;
        int dest = -1;
        int n = arr.size();
        while(cur<n)
        {
            if(arr[cur] != 0 )
            {
                dest++;
            }
            else
            {
                dest+=2;
            }
            if(dest >= n-1)
            {
                break;
            }
            cur++;
        }

        //1.5
        //处理边界情况
        if(dest == n)
        {
            arr[n-1] = 0;
            cur--;
            dest -= 2;
        }

        //2.完成复写
        while(cur>=0)
        {
            if(arr[cur] != 0 )
            {
                arr[dest] = arr[cur];
                dest--;
                cur--;
            }
            else
            {
                arr[dest--] = 0;
                arr[dest--] = 0;
                cur--;
            }
        }
    }
};

🛎️感谢各位同伴的支持,本期C++就讲解到这啦,如果你觉得写的不错的话,可以给个一键三连,点赞,关注+收藏,若有不足,欢迎各位在评论区讨论。    

  • 34
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值