返回
用 JavaScript 化腐朽为神奇:巧妙删除有序数组中的重复项
前端
2024-02-12 11:01:29
引言
在编写算法时,我们经常会遇到处理数组的场景。其中一个常见问题就是删除数组中的重复项。对于无序数组,我们可以使用各种方法,例如哈希表或排序加遍历。然而,对于有序数组,我们可以采用一种更巧妙的方法,它不仅简洁高效,而且可以在原地修改输入数组,而无需使用额外的空间。
算法详解
我们提供的 JavaScript 代码巧妙地利用了有序数组的特性。它使用两个指针,一个指针指向当前元素,另一个指针指向下一个不重复的元素。算法步骤如下:
- 初始化两个指针:
i
指向数组的开头,j
指向数组的下一个不重复元素。 - 遍历数组,如果
nums[i]
与nums[j]
相等,则跳过nums[i]
并继续前进。 - 如果
nums[i]
与nums[j]
不相等,则将nums[j]
的值赋给nums[i]
,然后将j
向前移动一位。 - 重复步骤 2 和 3,直到遍历完整个数组。
- 返回
j
,它表示删除重复项后的数组新长度。
代码实现
/**
* 原地删除有序数组中的重复项
* @param {number[]} nums 有序数组
* @return {number} 删除重复项后的数组新长度
*/
const removeDuplicates = (nums) => {
if (!nums || nums.length === 0) {
return 0;
}
let i = 0;
let j = 1;
while (j < nums.length) {
if (nums[i] === nums[j]) {
j++;
} else {
i++;
nums[i] = nums[j];
j++;
}
}
return i + 1;
};
复杂度分析
- 时间复杂度:O(n),其中 n 为数组的长度。算法遍历数组一次,因此时间复杂度为 O(n)。
- 空间复杂度:O(1)。算法在原地修改输入数组,不需要额外的空间,因此空间复杂度为 O(1)。
示例
const nums = [1, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7];
const newLength = removeDuplicates(nums);
console.log(`删除重复项后的数组:${nums}`);
console.log(`新长度:${newLength}`); // 输出:8
结论
我们巧妙地利用了有序数组的特性,设计了一种简洁高效的算法来删除重复项。该算法在不使用额外数组空间的情况下,原 地 修改输入数组,并且时间复杂度仅为 O(n)。掌握这种算法,将大大提升你的 JavaScript 编码能力,助你写出更出色的代码!