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)
相关推荐
白兰地空瓶4 分钟前
你以为树只是画图?不——它是算法面试的“隐形主角”
前端·javascript·算法
柒.梧.12 分钟前
数据结构:二叉排序树的删除操作实现
数据结构
好易学·数据结构14 分钟前
可视化图解算法74:最小花费爬楼梯
数据结构·算法·leetcode·动态规划·力扣
Maỿbe39 分钟前
力扣hot图论部分
算法·leetcode·图论
LYFlied1 小时前
【每日算法】LeetCode 78. 子集
数据结构·算法·leetcode·面试·职场和发展
月明长歌1 小时前
【码道初阶】【Leetcode606】二叉树转字符串:前序遍历 + 括号精简规则,一次递归搞定
java·数据结构·算法·leetcode·二叉树
子枫秋月1 小时前
C++字符串操作与迭代器解析
数据结构·算法
鹿角片ljp1 小时前
力扣234.回文链表-反转后半链表
算法·leetcode·链表
(●—●)橘子……1 小时前
记力扣1471.数组中的k个最强值 练习理解
数据结构·python·学习·算法·leetcode
oioihoii1 小时前
C++共享内存小白入门指南
java·c++·算法