LeetCode 去除有序数组中的重复项
数组相关经常会遇到需要删除数组中重复的元素,仅留下一个或多个不同的元素的情况。本文将介绍删除有序数组中的重复项算法,涉及了双指针法和哈希表两种解法。
一、问题描述
给定一个有序数组 nums,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回删除后数组新的长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
二、解法一:双指针法
有序数组中的删除重复项,可以通过双指针法来实现。定义两个指针 和 ,指向数组的头部。当 与 相等时,将 向后移动。若它们不相等,则将 的下一个位置设置为 的值,同时将 向后移动一个位置。当 指针到达数组末尾时, 指针的位置即为结果数组的长度。
下面的示例代码演示了如何在Java中使用双指针法来删除重复项:
class Solution {
public int removeDuplicates(int[] nums) {
if (nums.length == 0) {
return 0;
}
int i = 0;
for (int j = 1; j < nums.length; j++) {
if (nums[j] != nums[i]) {
i++;
nums[i] = nums[j];
}
}
return i + 1;
}
}
首先,我们在数组前两个元素中留下了一个不同的元素,之后我们使用例子中描述的方法逐步将指针移到末尾。
时间复杂度为 ,空间复杂度为 。
三、解法二:哈希表法
通常情况下,哈希表都是用来存储具有唯一性的个体,并可以使用空间换时间的方式来完成快速查找。在本问题中,哈希表可以同时满足数据去重的需求。我们可以在遍历的过程中使用哈希表来记录已经遇到的数字并筛选出不同的数字。以下是使用哈希表实现的代码:
class Solution {
public int removeDuplicates(int[] nums) {
if (nums.length == 0) {
return 0;
}
Map<Integer, Integer> map = new HashMap<>();
int n = nums.length;
int i = 0;
for (int j = 0; j < n; j++) {
if (!map.containsKey(nums[j])) {
map.put(nums[j], 1);
nums[i] = nums[j];
i++;
}
}
return i;
}
}
四、两种解法的比较
双指针法避免了使用额外的空间,因为只需要在输入数组内部完成相应重复项的删除操作。与之相比,哈希表解法相对较繁琐,但哈希表的好处是可以对于非有序的数组进行操作,并且哈希表可以方便地拓展到复杂的数据结构之上。
需要注意的是,哈希表的实现需要额外的数据结构空间。在本例中,我们需要创建一个哈希表来存储数据,并且返回的也就是删除完重复元素后的新数组长度。在其他问题中,哈希表用于存储其它的辅助信息,空间存储的占用也会跟着增加。
五、总结
本文介绍了两种解决「有序数组中的删除重复项」问题的方法,分别是双指针和哈希表。双指针法可以在不需要额外空间的情况下,通过原地操作达到删除重复元素的目的。哈希表相对来说更适用于其他情况。这两种方法都非常有用,具体使用应根据具体情况来决定。