首页 > 算法与数据结构 > 最新文章

【LeetCode原地复写零】:双指针+逆向填充,O(n)时间O(1)空间最优解!

CSDN博客 2026-05-06 03:09:30 人看过


一、复写零

在这里插入图片描述

二、思路分析

复写零这道题是让在原数组修改,如果从前向后遍历,后面的元素会被覆盖,所以我们要找到被复写的最后一个元素,然后从后往前复写。运用双指针+逆向填充

1.找到复写的最后一个数

定义两个指针:cur遍历原数组,pre模拟复写后的数组指针;

cur==0时,pre向后移动两位,cur!=0时,pre向后移动两位(因为要复写0);

当pre>=n-1时,停止遍历,这时,cur指的就是要复写的最后一个元素

在这里插入图片描述


边界情况:如下面这种情况,pre == n时,说明要复写的最后一个元素是0,这里单独处理

将数组最后一位改为0,也就是n==0;

cur向前移动一位,pre向前移动两位;

在这里插入图片描述

2.开始从后往前复写

从cur向前遍历,cur != 0时,就让arr[pre] == arr[cur];
cur == 0时,就让pre和pre-1位置的数都改为0,然后继续向前复写。
在这里插入图片描述

三、  代码              展示

class Solution {    public void duplicateZeros(int[] arr) {         int cur = 0, pre = -1, n = arr.length;        //1.找到要复写的最后一个元素        while(cur < n){            if(arr[cur] == 0){                pre += 2;            }else{                pre++;            }            if(pre >= n-1){                break;            }            cur++;        }        //处理边界情况        if(pre == n){            arr[n-1] = 0;            cur--;            pre -= 2;        }        //开始从后向前复写        while(cur >= 0){        if(arr[cur] != 0){            arr[pre--] = arr[cur--];        }else{            arr[pre--] = 0;            arr[pre--] = 0;            cur--;        }      }    } }

四、时间和空间复杂度分析

时间复杂度O(n):只需要遍历数组两次,第一次定位边界,第二次逆向填充;

空间复杂度O(1):使用的原数组,没有额外空间

五、总结

本解法通过双指针先定位复写边界,再逆向填充数组,既避免了正向遍历的元素覆盖问题,又实现了 O(n) 线性时间复杂度与 O(1) 常数空间复杂度的最优表现。其中“先确定边界、再逆向操作”的思路,是解决数组原地修改类问题的关键技巧,具有较强的通用性与实用性。

版权声明:倡导尊重与保护知识产权。未经许可,任何人不得复制、转载、或以其他方式使用本站《原创》内容,违者将追究其法律责任。本站文章内容,部分图片来源于网络,如有侵权,请联系我们修改或者删除处理。

编辑推荐

热门文章