在问 · 算法题解

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

题目描述

输入一个已按非递减顺序排好的整数数组 nums。设其中不同的值共有 k 个。

直接在 nums 上修改:让前 k 个位置依次放着这 k 个不同的值,每个值只出现一次,顺序与它们在原数组中的顺序一致。下标 k 及之后放什么都可以。

函数返回 k。判题时会检查返回值,并逐个核对 nums 的前 k 个元素。

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

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

解释:不同的值有 1 和 2 两个,返回 2,nums 前两位是 [1,2]。

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

解释:不同的值有 5 个,返回 5,nums 前五位是 [0,1,2,3,4]。

数据范围

  • 1 <= nums.length <= 3 * 10^4
  • -100 <= nums[i] <= 100
  • nums 已按非递减顺序排好。

解题思路

k 表示已经写好的去重前缀长度。顺序扫描每个 x:如果前缀为空,或 x 与前缀最后一个数 nums[k-1] 不同,x 就是新值,写到 nums[k] 并让 k 加 1;否则 x 是重复值,直接跳过。

为什么正确

每处理完一个元素,nums[:k] 恰好是已扫描部分的所有不同值,按原顺序排列。

复杂度分析

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

易错点

要和前缀最后一个数 nums[k-1] 比较,不要和原数组的前一个数 nums[i-1] 比较。前面的位置可能已经被改写。

参考代码

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

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

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

双指针 专题的其他题目

查看 双指针 全部题目 →