leetcode经典面试150题---4.删除有序数组中的重复项II

目录

题目描述

前置知识

代码

[方法一 双指针](#方法一 双指针)

思路

图解

实现

复杂度


题目描述


给你一个有序数组 nums ,请你**原地** 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在 原地修改输入数组并在使用 O(1) 额外空间的条件下完成

示例 1:

复制代码
输入:nums = [1,1,1,2,2,3]
输出:5, nums = [1,1,2,2,3]
解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3。 不需要考虑数组中超出新长度后面的元素。

示例 2:

复制代码
输入:nums = [0,0,1,1,1,1,2,3,3]
输出:7, nums = [0,0,1,1,2,3,3]
解释:函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3。不需要考虑数组中超出新长度后面的元素。

前置知识


  • 双指针

代码


方法一 双指针

思路

  • 首先我们注意到题目要求原地修改,那么肯定就需要一个指针指向当前即将放置元素的位置,需要另外一个指针向后遍历所有元素,所以「双指针」解法就呼之欲出了。
  • 慢指针 slow : 指向当前即将放置元素的位置;则 slow - 1 是刚才已经放置了元素的位置。
  • 快指针 fast : 向后遍历所有元素;
  • 因为最多允许两个重复元素,并且 slow - 2 位置是上上次放置了元素的位置,所以让 nums[fast] 跟 nums[slow - 2] 进行比较。每次都是只允许最多两个元素出现重复,这两个元素的位置在 slow - 1 和 slow - 2

动图

实现

java 复制代码
public class Solution {
    public int removeDuplicates(int[] nums) {
        int slow = 0;
        for (int fast = 0; fast < nums.length; fast++) {
            if (slow < 2 || nums[fast] != nums[slow - 2]) {
                nums[slow] = nums[fast];
                slow++;
            }
        }
        return slow;
    }
}

复杂度

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
相关推荐
FakeOccupational1 小时前
【数学 密码学】量子通信:光的偏振&极化的量子不确定性特性 + 量子密钥分发 BB84算法步骤
算法·密码学
ZhengEnCi3 小时前
S10-蓝桥杯 17822 乐乐的积木塔
算法
贾斯汀玛尔斯3 小时前
每天学一个算法--拓扑排序(Topological Sort)
算法·深度优先
大龄程序员狗哥3 小时前
第25篇:Q-Learning算法解析——强化学习中的经典“价值”学习(原理解析)
人工智能·学习·算法
exp_add33 小时前
质数相关知识
算法
小辉同志4 小时前
215. 数组中的第K个最大元素
数据结构·算法·leetcode··快速选择
小O的算法实验室5 小时前
2025年IEEE TITS,基于矩阵的进化计算+面向无线传感器网络数据收集无人机路径规划,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
OidEncoder5 小时前
编码器分辨率与机械精度的关系
人工智能·算法·机器人·自动化
memcpy05 小时前
LeetCode 2615. 等值距离和【相同元素分组+前缀和;考虑距离和的增量】中等
算法·leetcode·职场和发展
炽烈小老头5 小时前
【 每天学习一点算法 2026/04/22】四数相加 II
学习·算法