首页 > 编程语言 >算法:双指针

算法:双指针

时间:2024-08-26 13:52:07浏览次数:9  
标签:arr cur 指向 dest 算法 复写 指针

题目:复写零

虽然题目说必须要就地但是我们可以先试试异地然后再想办法优化成本地

算法讲解:

异地

可以定义两个指针让它们分别指向本地和异地,当本地指针指向零时这时候就往异地写入两个零其余就照常写,说完异地做法那我们应该如何优化成就地做法呢?

就地

本地也要定义两个指针

往前

cur往前每走一步时dest也会跟一步当cur指向0时dest会指向cur前面一个并且把它变成零那这样cur前面永远都是零了。

既然往前遍历不行那往后呢?

往后

要考虑 curdest 应该分别指向哪里。如果 cur 依然指向0,dest 指向-1,那和前向遍历是一样的,没有区别。但从题目中可以看到,输出结果的最后一个数字是4,而不是0。因此,我们可以将 cur 指向4的位置。cur 既然在前向遍历时指向第一个元素,那在后向遍历时指向输出结果的最后一个元素也是合理的。这样,cur 的位置已经确定了。那么 dest 应该指向哪里呢?

dest 是指向0还是5,或者其他位置?这个位置不好判断。不妨直接开始遍历。当 cur 指向4时,dest 应该复写4的位置;当 cur 指向0时,dest 应该将4和5都复写为0。这样我们可以推断出 dest 的位置。

找最后一个被复写数的位置

我们希望找到复写后数组的最后一个元素,但直接继续往后遍历显然不行。尽管通过题目我们知道最后一个元素的值,但是遍历的结束条件是什么呢?因此,我们需要改变策略:从往前遍历转为使用“快慢指针”方法。

快指针比慢指针走得更快。当快指针到达数组的末尾或空位时,慢指针应该指向正确的位置。这样我们就可以确保通过快慢指针的方法定位到数组复写后指定的最后一个元素。

但是,需要注意的是,这种方法也是有限制的。具体来说,当 cur 指向0时,dest 需要往前走两步,而在其他情况下,dest 只需要往前走一步。

边界问题

在力扣上的题目只要是野指针就会报错,那在上面我们说过“当快指针到达数组的末尾或空位时”其中只要指针指向空位就会报错,那该如何解决呢?

cur 指向0时,如果剩下的空间不足2个位置,会导致 dest 出现越界。这时我们可以直接将最后一个位置修改为0。这背后的原因是,如果空间不足两个位置,那最后一个位置必然是0,不然 dest 就不会越界。因此,我们可以放心地将其修改为0。

一旦最后一个位置被复写为0,意味着复写操作已经完成。这时,cur 应该向前移动一位,dest 也需要向前移动。不过,由于复写0需要占用两个位置,所以 dest 应该减去2。

代码实现:

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

标签:arr,cur,指向,dest,算法,复写,指针
From: https://blog.csdn.net/m0_72625526/article/details/141557614

相关文章

  • Python集成学习和随机森林算法使用详解
    概要集成学习是一种通过组合多个模型来提高预测性能的机器学习方法。它通过将多个弱学习器的结果结合起来,形成一个强学习器,从而提升模型的准确性和稳健性。随机森林(RandomForest)是集成学习中一种非常流行且有效的算法,特别适用于分类和回归任务。本文将详细介绍Python中如何......
  • 代码训练营 Day9 | 151.翻转字符串里的单词 | 认识KMP算法
    151.翻转字符串里的单词这道题的难度在于如何高效率的处理空格对于python来说不能实现空间O(1)的复杂度,不过对于其他语言来说下面思路可以使用双指针方法同时指向数组的头部循环遍历整个字符串直到数组末尾快指针不能为空,因为快指针是要获取字母的,慢指针是用来获取新的字......
  • 免费分享一套Java协同过滤推荐算法的SpringBoot+Vue(图书)商城系统【论文+源码+SQL脚
    大家好,我是java1234_小锋老师,看到一个不错的Java协同过滤推荐算法的SpringBoot+Vue(图书)商城系统,分享下哈。项目视频演示【免费】Java协同过滤推荐算法的SpringBoot+Vue(图书)商城系统Java毕业设计_哔哩哔哩_bilibili项目介绍伴随着Internet的蓬勃发展,电子商务也取得了......
  • 排序算法
    冒泡排序冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。......
  • 国密算法简介
    加密算法公开密钥长度分组长度分类加密强度其他SM1否128128对称密码AESSM2是128128非对称密码大于RSA基于ECC,加密强度和运算速度均大于RSASM3是128128单向散列密码MD5校验结果256SM4是128128对称密码(分组密码)AESSM9是128128......
  • 堆排序算法及优化(java)
    目录1.1引言1.2堆排序的历史1.3堆排序的基本原理1.3.1堆的概念1.3.2堆排序的过程1.3.3堆调整1.3.4堆排序算法流程1.4堆排序的Java实现1.4.1简单实现1.4.2代码解释1.4.3优化实现1.4.4代码解释1.5堆排序的时间复杂度1.5.1分析1.5.2证明1.6堆排序......
  • 算法与数据结构——内存与缓存
    内存与缓存数组和链表两种数据结构分别代表了“连续存储”和“分散存储”两种物理结构。实际上,物理结构在很大程度上决定了程序对内存和缓存的使用效率,进而影响算法程序的整体性能。计算机存储设备计算机中包括三种类型的存储设备:硬盘(harddisk)、内存(random-accessmemory,RAM)、......
  • 深入理解指针(下)
    1.数组名的理解首先分析下面这段代码intarr[10]={1,2,3,4,5,6,7,8,9,10};int*p=&arr[0];这里我们使用 &arr[0]的方式拿到了数组第⼀个元素的地址,但是其实数组名本来就是地址,而且是数组首元素的地址,我们来做个测试。输出结果为我们发现......
  • 47.【C语言】指针(重难点)(J)
    目录26.自制排序函数(★★)    *分析    *代码往期推荐26.自制排序函数*分析之前在42.【C语言】冒泡排序写过一个排序函数,可以将此自制一个类似qsort的函数画圈的地方是需要修改的#include<stddef.h>voidbubble_sort(void*base,size_tnum,size_tw......
  • 电商导购平台的推荐算法与大数据应用
    电商导购平台的推荐算法与大数据应用大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!电商导购平台的核心竞争力之一就是为用户提供个性化的购物体验,而推荐算法和大数据技术的应用是实现这一目标的关键。本文将探讨电商导购平台中推荐算法的设计......