在问 · 算法题解

80. 删除有序数组中的重复项 II

题目描述

输入数组 nums,它已按非递减顺序排好。

在原数组上删去多余的重复元素,使每个值最多保留两个,且保持原有的相对顺序。设剩下 k 个元素,它们要放在 nums 的前 k 个位置,k 之后的位置放什么都可以。

函数返回 k。只能用 O(1) 额外空间,不能另开数组。

本页的输出写成 [k, nums 的前 k 个元素]。

示例 1
输入:nums = [1,1,1,2,2,3]
输出:[5,[1,1,2,2,3]]

解释:三个 1 只保留两个,剩下 5 个元素 [1,1,2,2,3]。

示例 2
输入:nums = [0,0,1,1,1,1,2,3,3]
输出:[7,[0,0,1,1,2,3,3]]

解释:四个 1 只保留两个,剩下 7 个元素。

数据范围

  • 1 <= nums.length <= 3 * 10^4
  • -10^4 <= nums[i] <= 10^4
  • nums 已按升序排列。

解题思路

快慢指针。k 是保留前缀的长度,也是下一个写入位置。读到 x 时,如果前缀不足两个,或 nums[k−2] ≠ x,就把 x 写到 nums[k]。数组有序,nums[k−2] == x 说明前缀末尾已经有两个 x,再放就是第三个。

为什么正确

nums[:k] 是已读部分中每个值最多保留两次后的结果,并且仍然有序。

复杂度分析

时间 O(n),空间 O(1)。

易错点

要和前缀里的 nums[k−2] 比,不是和原数组的 nums[i−2] 比:原位置可能已被覆盖,也可能包含已丢弃的重复值。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        k = 0
        for x in nums:
            if k < 2 or nums[k - 2] != x:
                nums[k] = x
                k += 1
        return k

载入编辑器,自己跑一遍 →

双指针 专题的其他题目

查看 双指针 全部题目 →