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 位置是上上次放置了元素的位置,所以让 numsfast 跟 numsslow - 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)
相关推荐
Jerry1 小时前
LeetCode 151. 反转字符串中的单词
算法
gugucoding2 小时前
31. 【C语言】堆栈与队列的实现
c语言·开发语言·数据结构·链表
ChaoZiLL3 小时前
我的数据结构3——链表(link list)
数据结构·链表
a1117763 小时前
LM 算法迭代过程动画演示(SLAM)
算法
头茬韭菜4 小时前
Context 的生死抉择:四层压缩、截断算法与 Session Memory
算法·ai
Jerry4 小时前
LeetCode 541. 反转字符串 II
算法
Jerry4 小时前
LeetCode 344. 反转字符串
算法
搞科研的小刘选手4 小时前
【香港大学主办&IEEE出版】第六届计算机视觉、应用与算法国际学术会议(CVAA 2026)
算法·计算机视觉·应用·学术会议
Java小白笔记5 小时前
Codex config.toml配置实战指南
人工智能·算法·chatgpt·ai编程·集成学习
王老师青少年编程5 小时前
2026年6月GESP真题及题解(C++七级):消消乐
数据结构·c++·算法·真题·gesp·2026年6月