[C++]算法双指针 复写0

题目描述:

题目来源:力扣「复写零」

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

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

算法原理:

双指针算法:先根据"异地",然后优化完成双指针下的"就地"操作。

一、先找到最后一个"复写"的数:

**双指针算法:

  1. 将 cur 赋值为 0,dest 赋值为 -1;先判断 cur 位置的值**

2提高cur的值决定dest向后一步还是两步

3.判断一下dest是否已经到结束位置

4.cur++

一.五. 处理一下边界情况

将n-1位置的数据改成0

cur--

dest-=2

二."从后向前"完成复写操作

处理边界情况

从后向前完成复写;

cpp 复制代码
class Solution 
{
public:
    void duplicateZeros(vector<int>& arr) 
    {
        //1.先找到最后一个复写的数
          int cur =0;      // cur 指向当前遍历的原数组位置,从下标 0 开始
          int dest =-1;    // dest 指向复写后数组的最后一个有效位置,初始为 -1(表示尚未确定)
          int n =arr.size();  // n 为数组长度,用于判断边界
          while(cur<n)     // 遍历原数组,直到 cur 越界
          {
            if(arr[cur]) dest++;   // 当前元素非 0,复写后只占 1 个位置,dest 向后移动 1 步
            else dest+=2;          // 当前元素为 0,复写后占 2 个位置,dest 向后移动 2 步
            if(dest>=n-1)          // 若 dest 已到达或超过数组最后一个下标,说明已找到最后一个被复写的数的位置
              break;               // 跳出循环,此时 cur 指向的就是最后一个被复写的数
            cur++;                 // 否则继续向后遍历原数组
          }
          //2.处理边界情况
          if(dest ==n)             // 若 dest 恰好越界到 n(即最后一个复写的是 0,且它只占最后 1 个位置)
          {
            arr[n-1]=0;            // 将数组最后一个位置直接写成 0
            cur--;                 // cur 回退一步,跳过这个已经被处理的 0
            dest-=2;               // dest 回退 2 步,回到前一个有效写入位置
          }
        //3.从后往前复写数组
        while(cur>=0)              // 从最后一个被复写的数开始,从后向前遍历原数组
        {
           if(arr[cur])            // 当前元素非 0
            {
                arr[dest--]=arr[cur--];  // 直接把它写到 dest 位置,dest 和 cur 各向前移动 1 步
            }
            else                   // 当前元素为 0
              {
                arr[dest--]=0;     // 先写一个 0 到 dest 位置,dest 向前移动 1 步
                arr[dest--]=0;     // 再写一个 0 到前一个位置,dest 再向前移动 1 步(复写两个 0)
                cur--;             // cur 向前移动 1 步,继续处理前一个元素
               }
        }
}
};

复杂度分析:

时间复杂度:O(n)。整个算法只对数组进行常数次线性扫描,因此时间复杂度为 O(n)。

空间复杂度:O(1) 。算法只使用了 cur、dest、n 等常数个额外变量,并且所有复写操作都在原数组 arr 上就地完成,没有借助额外的数组或容器,因此空间复杂度为 O(1)。

相关推荐
vvilkim14 分钟前
数据结构类型、区别与应用场景:一篇讲透选型逻辑
数据结构
努力努力再努力wz1 小时前
【Lua 进阶系列】从 C++ 对象到 Lua 变量:一文理解 userdata、Lua 栈与元表绑定机制
c++·junit·lua
慧都产品智能化2 小时前
Qt 表格升级攻略:复用已有编辑器,减少重复开发
c++·qt·编辑器·qt6.3
ShineWinsu2 小时前
对于Qt:QTableWidget常见属性以及QTableWidgetItem类的解析
开发语言·c++·qt·gui·客户端·表格·qtablewidget
ShineWinsu3 小时前
对于Qt:QListWidget常见属性以及QListWidgetItem类的解析
开发语言·c++·qt·客户端·列表·qlistwidget·qlistwidgetitem
坤坤子吖4 小时前
Linux网络编程:自定义应用层协议与 JSON 序列化
linux·服务器·网络·c++·笔记·json
lisw054 小时前
Dayhoff的PAM替换矩阵理论评介!
线性代数·算法·矩阵
阿卡好可爱5 小时前
Lua 热更新不生效:改完文件线上仍是旧逻辑,package.loaded 与 upvalue 重绑定详解
数据结构·分布式·后端·架构·lua
一起学安全技术5 小时前
拆大模型 03|注意力的一句话版本:不用论文讲清 Attention
深度学习·算法·语言模型·transformer
沫璃染墨5 小时前
从零入门计算机网络系列(十八):TCP连接管理详解——从三次握手与四次挥手到TIME_WAIT机制
运维·服务器·网络·c++·网络协议·tcp/ip·tcp