首页 > 编程语言 >(算法)双指针——复写零 <原地复写>

(算法)双指针——复写零 <原地复写>

时间:2024-05-28 23:58:59浏览次数:21  
标签:arr cur 从后 dest -- 算法 复写 指针

1. 题⽬链接:1089.复写零

2. 题⽬描述:

3. 解法(原地复写-双指针): 

算法思路: 

如果「从前向后」进⾏原地复写操作的话,由于0 的出现会复写两次,导致没有复写的数「被覆 盖掉」。因此我们选择「从后往前」的复写策略。 但是「从后向前」复写的时候,我们需要找到「最后⼀个复写的数」,因此我们的⼤体流程分两 步:

i. 先找到最后⼀个复写的数;

ii. 然后从后向前进⾏复写操作。

算法流程: 

a. 初始化两个指针cur = 0 , dest = 0 ; 

b. 找到最后⼀个复写的数: 

        i. 当cur < n 的时候,⼀直执⾏下⾯循环: 

                • 判断cur 位置的元素: ◦ 如果是0 的话, dest 往后移动两位; ◦ 否则, dest 往后移动⼀位。                 

                • 判断dest 时候已经到结束位置,如果结束就终⽌循环; 

                • 如果没有结束, cur++ ,继续判断。

c. 判断dest 是否越界到n 的位置: 

        i. 如果越界,执⾏下⾯三步:

                1. n - 1 位置的值修改成0 ; 

                2. cur 向移动⼀步;

                3. dest 向前移动两步。 

d. 从cur 位置开始往前遍历原数组,依次还原出复写后的结果数组: 

        i. 判断cur 位置的值: 

                1. 如果是0 : dest 以及dest - 1 位置修改成0 , dest -= 2 ; 

                2. 如果⾮零: dest 位置修改成0 , dest -= 1 ;

         ii. cur-- ,复写下⼀个位置。

C++算法代码: 

class Solution {
public:
    void duplicateZeros(vector<int>& arr)
    {
        //先找到最后一个数
        int cur = 0, dest = -1;
        while (cur < arr.size())
        {
            //当元素非0
            if (arr[cur])
            {
                dest++;
            }
            else
            {
                dest += 2;
            }
            //当复写范围占满数组范围
            if (dest >= arr.size() - 1)
            {
                break;
            }
            cur++;
        }
        //处理边界情况,超出范围一位,说明arr[cur]==0
        if (dest == arr.size())
        {
            //将未超出范围的复写0初始化
            arr[arr.size() - 1] = 0;
            //将操作流程往前推一次,解决dest的越界
            cur -= 1;
            dest -= 2;
        }
        //从后往前完成复写操作
        while (cur >= 0)
        {
            //当cur位置的数非零,则再dest处写入一次
            if (arr[cur])
            {
                arr[dest--] = arr[cur--];
            }
            else    //cur处为0时,再dest前一位和所在为都复写为0
            {
                arr[dest--] = arr[cur];
                arr[dest--] = arr[cur];
                cur--;
            }
        }
    }
};

Java算法代码:

class Solution 
{
 public void duplicateZeros(int[] arr) 
 {
 int cur = 0, dest = -1, n = arr.length;
 // 1. 先找到最后⼀个需要复写的数 
 while(cur < n)
 {
 if(arr[cur] == 0) dest += 2;
 else dest += 1;
 if(dest >= n - 1) break;
 cur++;
 }
 // 2. 处理⼀下边界情况 
 if(dest == n)
 {
 arr[n - 1] = 0;
 cur--; dest -= 2;
 }
 // 3. 从后向前完成复写操作 
 while(cur >= 0)
 {
 if(arr[cur] != 0) arr[dest--] = arr[cur--];
 else
 {
 arr[dest--] = 0;
 arr[dest--] = 0;
 cur--;
 }
 }
 }
}

标签:arr,cur,从后,dest,--,算法,复写,指针
From: https://blog.csdn.net/2301_79580018/article/details/139247647

相关文章

  • 二分查找算法详讲(三种版本写法)原创
    介绍:二分查找算法(BinarySearch)是一种在有序数组中查找目标元素的算法。它的基本思想是通过将目标元素与数组的中间元素进行比较,从而将搜索范围缩小一半。如果目标元素等于中间元素,则搜索结束;如果目标元素小于中间元素,则继续在左半部分查找;如果目标元素大于中间元素,则在右......
  • 基于BP神经网络的32QAM解调算法matlab性能仿真
    1.算法运行效果图预览   2.算法运行软件版本matlab2022a 3.算法理论概述       32QAM(QuadratureAmplitudeModulation,四相幅度调制)是一种高效的数字调制技术,能够在一个信道内同时传输多比特信息。基于BP(Backpropagation)神经网络的32QAM解调算法,利用神经网......
  • 数据结构与算法学习——二叉树
    题目PS:下列题目均来自leetcode中灵神题单938.二叉搜索树的范围和classSolution:defrangeSumBST(self,root:TreeNode,low:int,high:int)->int:ifnotroot:return0ifroot.val>high:returnself.rangeSumBST(r......
  • 想要初步了解指针?看这篇就够啦!
    初级指针    一:指针的解释        什么是指针?本质上指针是内存地址,平时说的指针是指针变量,用来存放地址,指针变量里面存放的是地址而通过这个地址,就可以找到一个内存单元            上示例,定义了int类型的a变量,声明了一个整型......
  • 数据结构与算法
    数据结构与算法导航目录数据结构与算法导航一、数据结构与算法概念数据结构的定义算法伪代码二、线性表线性表三、队列与栈栈队循环队列四、窜广义表窜五、数组六、树与二叉树树二叉树七、图图的存储八、查找五大查找顺序查找二分查找二叉查找树(排序)二叉平衡树哈夫曼树B-树B+......
  • 031 指针学习—引用数组
    目录1数组元素的指针(1)定义(2)举例(3)注意事项2指针的算术运算(1)前提(2)运算规则(3)举例[1]p+i[2]p-i[3]++p与p++[4]--p与p--[5]p1-p2(4)注意事项3通过指针引用数组元素(1)引用数组元素方法(2)举例例1:输出a[10]数组中的全部元素例2:通过指针变量输出整型数组a的10个......
  • 旅行第三天【算法】双指针-----盛最多水的容器
    文章目录一、题目二、算法原理三、编写代码一、题目链接:盛最多水的容器二、算法原理首先,这种题可以用暴力解法(枚举每一种容器的大小情况),但是显然会超时(不用尝试啦,我已经试过啦!)其次还是咱们的主题----->利用双指针来求解下面先附上草稿图容器面积=高度(左......
  • 【LeetCode算法】第88题:合并两个有序数组
    目录一、题目描述二、初次解答三、官方解法四、总结一、题目描述二、初次解答1.思路:首次想到的解法:定义一个m+n长度的辅助数组,从头遍历这两个数组,谁小就放进辅助数组中并且对应往后走,最后使用memcpy函数将辅助数组内容拷贝到nums1中。这种解法容易想到,但是空间复杂......
  • 【LeetCode算法】第83题:删除排序链表中的重复元素
    目录一、题目描述二、初次解答三、官方解法四、总结一、题目描述二、初次解答1.思路:双指针法,只需遍历一遍。使用low指向前面的元素,high用于查找low后面与low不同内容的节点。将具有不同内容的节点链接在low后面,实现重复元素的删除。2.代码:/***Definitionfor......
  • 代码随想录算法训练营第七天|454(四数相加||),383(赎金信),15(三数之和),18(四数之和)
    哈希三数之和和四数之和,和两数之和一样,是对一个数组来进行检索。因为要求元组不能重复,需要用多指针的方法来遍历和判断。由于两数之和没有这个要求且要返回下标,所以用了哈希表。但哈希表难以检测是否重复,不如双指针直接。四数相加||是对四个数组来做相加,且不要求元组重复,可用哈......