返回

快速剔除重复元素,高效更新排序数组

闲谈

当我们面对一个有序数组,如何快速剔除其中的重复元素,实现数组的精简呢?本期 LeetCode 题解将带领大家详细解析第 26 题:删除排序数组中的重复项。

问题

给定一个排序数组,我们需要在原地删除重复出现的元素,使得每个元素只出现一次。请注意,输入数组是以"引用"方式传递的,这意味着我们在函数内所做的任何修改都会影响原数组。同时,我们必须在使用 O(1) 额外空间的条件下完成此操作。

解题思路

这道题可以用两种不同的方法来解决。第一种方法是使用双指针法,而第二种方法则是采用更直观的原地修改法。

双指针法:

  1. 首先初始化两个指针,ij,其中 i 指向数组的第一个元素,而 j 指向数组的第二个元素。
  2. 接着,我们比较这两个元素。如果它们相等,则将 j 向右移动一步,直到找到一个与前一个元素不同的元素。
  3. 然后,我们将 i 向右移动一步,并将 j 指向 i 后面的元素。
  4. 重复步骤 2 和步骤 3,直到 j 指向数组的最后一个元素。
  5. 最后,我们将 i 指向的元素作为新数组的最后一个元素,并返回 i 的值。

原地修改法:

  1. 首先,我们初始化一个变量 count,用于记录不重复元素的个数。
  2. 接着,我们遍历数组,对于每一个元素,如果它与前一个元素不同,则我们将 count 加 1,并将该元素复制到数组的第 count 个位置。
  3. 最后,我们将 count 作为新数组的长度,并返回它。

实现代码

def remove_duplicates(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    # 双指针法
    # i 指向当前元素,j 指向下一个元素
    i = 0
    j = 1

    # 当 j 小于数组长度时,继续循环
    while j < len(nums):
        # 如果当前元素与下一个元素不同,则将当前元素复制到下一个位置,并移动 i 和 j 指针
        if nums[i] != nums[j]:
            i += 1
            nums[i] = nums[j]
        # 否则,只移动 j 指针
        else:
            j += 1

    # 返回 i+1 作为新数组的长度
    return i+1


# 原地修改法
def remove_duplicates_inplace(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    # count 记录不重复元素的个数
    count = 0

    # 遍历数组
    for num in nums:
        # 如果当前元素与前一个元素不同,则将其复制到数组的第 count 个位置,并增加 count
        if count == 0 or num != nums[count - 1]:
            nums[count] = num
            count += 1

    # 返回 count 作为新数组的长度
    return count

总结

这道题考察了我们在数组操作和算法设计方面的能力。通过双指针法或原地修改法,我们都可以高效地解决问题。在实际开发中,我们可以根据具体情况选择合适的方法。