Java算法精讲:双指针(二)

📚 目录

  • [1. 题目解析](#1. 题目解析)

  • [2. 算法原理](#2. 算法原理)

  • [3. 编写代码](#3. 编写代码)

LeetCode 1089.复写零|Java双指针原地解题详解

原题链接:https://leetcode.cn/problems/duplicate-zeros/description/

1. 题目解析

  1. 数组是长度固定的整数数组 ,要求原地修改,不能额外开辟新数组空间,函数最终不需要返回任何数据;
  2. 遍历数组,每遇到一个0就额外复写一个0,该0之后所有元素整体向右平移;
  3. 填充元素不可超出原数组长度溢出 的数据直接舍弃

  数据占用规则:

  • 非0数字 :仅占用数组1个下标位置;
  • 数字0 :需要占用连续2个下标位置(原有0 + 复写新增的0)。

[🔙 返回目录](#🔙 返回目录)


2. 算法原理

  首先我们会想到第一种双指针的方法: 从前往后 的遍历处理

  我们定义两个指针:dest , cur 这两个指针:

  我们从下标0初始化双指针cur、dest:

  非0元素:cur、dest同步后移1位,原地赋值;

  遇见数字0:cur右移1位,dest向后跳2位,连续填入两个0;

  致命缺陷 :原地填充0 直接覆盖后面原始数据,cur继续右移只会读取刚填的0 ,后续所有元素不断被改写为0,算法完全出错。

  因此从前往后的双指针不可行

  前往后不可行,那么从后往前 呢?

  此时:从后往前的方法是可行的

  那我们是怎么知道要从4位置开始复写呢?

**  新问题:我们如何精准计算出cur的起始下标(示例里下标4)?**

  第一步:正向双指针,锁定反向填充起始下标cur从0开始,dest从-1开始

  规则:cur、dest从下标0同步出发

**  遍历元素非0:cur、dest同步向后+1;
  遍历元素为0:cur+1,dest向后+2(0要占用两个数组位置);**

  终止条件:dest走到数组最后一位下标,此时cur的位置就是倒序填充的起始位置 ,衔接下一阶段反向复写。

  此时我们还需要处理我们边界情况:

  当cur指向元素0时,dest+2会直接超出数组最大下标n-1,触发越界,需要单独处理:

   一旦dest > n-1,立刻跳出正向统计循环;

  手动把数组最后一位arr[n-1] = 0

  dest回退两步(dest = n-3),cur左移一格,正式开启反向从后向前填充。
[🔙 返回目录](#🔙 返回目录)


3. 编写代码

java 复制代码
class Solution {
    public void duplicateZeros(int[] arr) {
        int n = arr.length;
        int cur = 0;
        int dest = -1;
        //找开始位置
        while(cur<n) {
            if(arr[cur] == 0) {
                dest+=2;
            }else {
                dest+=1;
            }
            if(dest >= n-1) {
                break;
            }
            cur++;
        }
        //处理边界
        if(dest == n) {
            arr[n-1] = 0;
            dest -= 2;
            cur --;
        }

        while(cur >= 0) {
            if(arr[cur]!=0) {
                arr[dest--] = arr[cur--];
            }else{
                arr[dest--] = 0;
                arr[dest--] = 0;
                cur--;
            }
        }
    }
}

  结果:


[🔙 返回目录](#🔙 返回目录)


相关推荐
jeffer_liu1 小时前
Spring AI 生产级实战:裁判员
java·人工智能·后端·spring·大模型
何以解忧,唯有..2 小时前
Python包管理工具pip:从入门到精通
开发语言·python·pip
wayz112 小时前
Momentum:PSL(心理线指标)技术指标详解
算法·金融·数据分析·量化交易·特征工程
雪的季节2 小时前
RabbitMQ详解
开发语言
小bo波2 小时前
枚举实战
java·设计模式·枚举·后端开发·代码重构
8Qi82 小时前
LeetCode 213:打家劫舍 II(House Robber II)—— 题解 ✅
算法·leetcode·职场和发展·动态规划
ice8130331813 小时前
【Python】Matplotlib折线图绘制
开发语言·python·matplotlib
夜微凉43 小时前
三、Spring
java·后端·spring
三品吉他手会点灯3 小时前
C语言学习笔记 - 44.运算符和表达式 - 运算符2 - 除法与取余运算符
c语言·开发语言·笔记·算法