LeetCode - 1089. 复写零

题目

1089. 复写零 - 力扣(LeetCode)

思路

这道题我首先想到的是从前往后双指针,但是这样做会造成数据的覆盖,比如说下面的这个情况

所以解决的方法就是从后往前去复写,但是从后往前的话就要知道最后一个有效元素是什么。

对于这个情况,我们可以先去根据"异地操作"找到最后一个有效元素,需要一个cur指针,和一个dest指针,cur先进行判断,当遇到非0元素cur++,dest++,当遇到0元素,就让cur,dest+2,直到dest到数组的末端,判断此时的cur就是最后一个有效元素

再进行优化,我们就需要双指针下的"就地"操作

但是此时会有个特殊情况:当cur最后一个位置是0的时候,会导致dest+2的时候越界了,此时就会报错了

所以我们要处理这个边界情况,方法就是当查找有效位置的时候,跳出循环后,如果dest=n,此时说明cur指向的一定0(这样另外数的dest连跳两步所以才会越界),所以我们此时让dest-1的位置为0,然后dest-=2,cur-1

接下来就是

读者可能出现的错误写法

cpp 复制代码
class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int n = arr.size();
        int cur = 0;
        int dest = 0;

        while(arr[dest])
        {
            if(arr[cur]==0)
            {
                cur++;
                dest+=2;
            }
            else
            {
                cur++;
                dest++;
            }
        }

        while(arr[cur])
        {
            if(arr[cur]==0)
            {
                cur--;
                for(int i=0;i<2;i++)
                {
                    arr[dest] = 0;
                    dest--;
                }

            }
            else
            {
                arr[dest] = arr[cur];
                cur--;
                dest--;
            }  
        }

    }
};

第一个问题是循环条件写错了,while(arrdest) 这里有问题,你这样写的话,如果dest越界了,访问arrdest就会出错。应该改成 while(dest < n)。

第二个问题是第二个循环也有问题,while(arrcur) 这里也不对,应该改成 while(cur >= 0)。

第三个问题是缺少边界处理,你没有处理那种刚好在边界的特殊情况。

修改一下:首先第一个while循环应该是 while(dest < n),然后在循环里面如果arrcur等于0就让dest加2,否则dest加1,但是要记得加个判断if(dest >= n) break,然后cur++。

接下来要处理边界情况,如果dest==n的话,说明最后一个0只能写一半,所以arrn-1 = 0,然后dest减2,cur减1。

最后第二个while循环应该是while(cur >= 0),在循环里面如果arrcur是0就连续写两个0到dest位置,否则就把arrcur写到dest位置,记得每次都要cur和dest往前移。

dest表示"当前元素应该在的最终位置",因为我们不知道第一个元素应该在的位置,所以应该初始化为-1

cpp 复制代码
class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int n = arr.size();
        int cur = 0;
        int dest = -1;

        while(dest<n)
        {
            if(arr[cur]==0)
            {
                dest+=2;
            }
            else
            {
                dest++;
            }
            if(dest >= n-1) break;
            cur++;
        }

        if(dest>n-1)
        {
            arr[n-1] = 0;
            dest-=2;
            cur--;
        }

        while(cur>=0)
        {
            if(arr[cur]==0)
            {
                for(int i=0;i<2;i++)
                {
                    arr[dest] = 0;
                    dest--;
                }
            }
            else
            {
                arr[dest] = arr[cur];
                dest--;
            } 
            cur--; 
        }
    }
};
相关推荐
雨落在了我的手上1 小时前
Java数据结构(十一):优先级队列(堆)
数据结构
带多刺的玫瑰6 小时前
Leecode#26刷题之删除有序数组中的重复项
数据结构·算法·leetcode
洋不写bug8 小时前
二叉树(二) 常见基础操作解析|结点数、树高、查找结点、判断完全二叉树
java·开发语言·数据结构·完全二叉树·二叉树结点数·树高·查找结点
化雨成烟8 小时前
C++之AVL树
数据结构
wabs6669 小时前
关于二叉树【429.N叉树的层序遍历的思考】
数据结构·c++·算法·leetcode·二叉树
C++ 老炮儿的技术栈9 小时前
MFC CPtrArray的用法
开发语言·数据结构·c++·算法·mfc·c
不会就选b9 小时前
算法日常・每日刷题--<贪心>6
数据结构·算法·leetcode
青山木10 小时前
Hot 100 --- 跳跃游戏 II
java·数据结构·算法·leetcode·贪心算法
神明不懂浪漫11 小时前
【第四章】索引——B+树、回表,加快数据库的查找能力的利器
开发语言·数据结构·数据库·经验分享·笔记·b树
LuminousCPP12 小时前
数据结构 - 排序(二):快速排序从错误初版到优化版|双指针划分 + 三数取中 + 小区间插入优化
c语言·数据结构·笔记·算法·排序算法