题目描述
解法
方法一:删除多余的重复项
由于输入数组已经排序,所以重复项都显示在旁边。题目要求在原地修改数组,最简单的方法就是删除多余的重复项。对于数组中的每个数字,若出现 2 个以上的重复项,就将多余的重复项从数组列表中删除。
这里的删除是指将待删除项后面的全部数据向前挪一格,显然,这种算法的复杂度是O(N^2)
方法二:覆盖多余的重复项
这需要两个指针,即双指针,或者说是快慢指针也无所谓,因为快慢指针的含义是两个移动速度或者别的方面没有联系的指针。
到此,快慢指针的两个常见用法我都已经接触到了。一个是判断有无环,实质是判断有无重复项;另一个是这里学习的删除重复项
(所以遇到有关重复项的就想快慢指针 ???)
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int index = 0;
for(int i : nums)
{
if(index < 2 || i != nums[index - 2])
nums[index++] = i;
}
return index;
}
};
思路我不会组织语言,就举个例子吧,简洁明了
举例: 1 1 1 1 2 3 3
- 第一个指针是遍历数组的 i,为了简便,我把这里的 i 设置成nums[i],也就是说它不是遍历指针(或者说下标),而是挨着的一个个数组中的数
- 另一个指针是比 i 要更往前走的 index,用话术说 index 是要覆盖上去的元素的位置,不理解没关系,往下看它的功能也就明白了
- 首先 i = 1(也就是num[0]),index = 0
- 因为题目要求至多重复2次,那么 index < 2 时不需要考虑,跟着遍历数组的 i 走就行了,此时 nums = [1, 1] , i = 1(第二个1), index ++ 之后现在是2
- 再次进入for循环, index >=2 时就要小心多余重复了,允许的情况是 i != nums[index - 2],表示再往后是不重复的数。这里用 index - 2 是因为题目要求是至多重复2次,所以跟往前2个的数作比较(注意,index 是一直在自增的),如果要求不允许重复,这里就应该是 Index - 1 了(LeetCode - 26. 删除排序数组中的重复项)
这种算法的时间复杂度是O(n),因为是需要遍历数组一遍。
终于差不多说完了,其实理解了之后不是很难,但就是很难表述清楚我感觉(或许是我功力不够吧 orz)
本文介绍了如何使用双指针技巧在已排序数组中删除最多两次重复项,通过对比当前元素和前两个元素避免O(N^2)复杂度,达到线性时间复杂度O(n)。实例解析与代码实现清晰易懂。


313

被折叠的 条评论
为什么被折叠?



