返回

魔鬼数据结构刷题手册——前端刷题第80题:有序数组删除重复项Ⅱ

前端

前言

在前端开发中,我们经常会遇到处理数组数据的情况。数组是一种常见的数据结构,它可以存储一组有序或无序的数据项。在数组中,可能会存在重复元素。如果数组中的元素是按照一定顺序排列的,那么就可以称之为有序数组。在有序数组中,重复元素通常是连续出现的。删除有序数组中的重复元素是一种常见的问题。

题目

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用后返回新的数组长度。

解题思路

为了解决这个问题,我们可以使用双指针法。首先,我们将两个指针 i 和 j 都指向数组的第一个元素。然后,我们将指针 i 向右移动,直到遇到第一个重复的元素。当我们遇到重复的元素时,我们将指针 j 向右移动,直到遇到下一个不重复的元素。然后,我们将指针 i 指向指针 j,并继续向右移动指针 i 和 j。重复这个过程,直到我们遍历完整个数组。

代码示例

/**
 * 给定一个有序数组 nums ,请你 原地 删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。
 *
 * 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用后返回新的数组长度。
 *
 * 示例 1:
 *
 * 输入:nums = [1,1,1,2,2,3]
 * 输出:5
 * 解释:函数应该返回新的长度 5, 并且 nums 为 [1,1,2,2,3]。
 *
 * 示例 2:
 *
 * 输入:nums = [0,0,1,1,1,1,2,3,3]
 * 输出:7
 * 解释:函数应该返回新的长度 7,并且 nums 为 [0,0,1,1,2,3,3]。
 *
 * 提示:
 *
 * 0 <= nums.length <= 3 * 104
 * -104 <= nums[i] <= 104
 * nums 已按升序排列
 */
const removeDuplicates = (nums) => {
  if (nums === null || nums.length === 0) {
    return 0;
  }

  let i = 0;
  let j = 1;

  while (j < nums.length) {
    if (nums[i] === nums[j] && i - 1 >= 0 && nums[i] === nums[i - 1]) {
      j++;
    } else if (nums[i] === nums[j] && i - 1 < 0) {
      j++;
    } else {
      i++;
      nums[i] = nums[j];
      j++;
    }
  }

  return i + 1;
};

总结

在本文中,我们介绍了一种解决有序数组中删除重复元素的方法,并提供了一个实现该方法的前端代码示例。这种方法使用双指针法,可以高效地删除有序数组中的重复元素。这种方法的时间复杂度是 O(n),其中 n 是数组的长度。