LeetCode 80. 删除排序数组中的重复项 II(中)
原地算法解决重复项,参照90题 while
的用法,配合Python内建API删除重复的数值即可。
题目
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
示例
示例 1:
1 |
|
示例 2:
1 |
|
考察知识点
双指针、数组
核心思想
方法一、单指针
循环遍历,发现连续三个一样的就删去第三个。
调用了python内建的 del
函数完成删除。
方法二、双指针计数删除
用一个变量 cnt 来记录还允许有几次重复,cnt 初始化为1,如果出现过一次重复,则 cnt 加1。当cnt大于2时,说明出现第三次了,删除当前项,指针先回退再前进。当cnt小于等于2时,说明当前项出现次数小于2,调用了python内建的 pop
函数。
方法三、双指针覆盖
用 count 记录当前数字出现的次数。count 的最小计数始终为 1。
若当前元素与前一个元素相同,即 nums[i]==nums[i-1],则 count++。若 count > 2,则说明遇到了多余的重复项。在这种情况下,我们只向前移动 i,而 j 不动,i是快指针,j是慢指针。
若 count <=2,则我们将 i 所指向的元素移动到 j 位置,并同时增加 i 和 j。
若当前元素与前一个元素不相同,即 nums[i] != nums[i - 1],说明遇到了新元素,则我们更新 count = 1,并且将该元素移动到 j 位置,并同时增加 i 和 j。
注意,这种方法没有真正的将数据从list中删除,而是向前覆盖了。
Python版本
- 方法一单指针算法的实现
1 |
|
时间复杂度:\(O(n) + O(n^2)\),循环遍历了整个数组,每次删除操作 del
的时间复杂度是 \(O(n^2)\),所以总的时间复杂度为 \(O(n) + O(n^2)\)。
空间复杂度:\(O(1)\),仅仅申请了一个常数级别的额外空间。
执行用时 :40 ms, 在所有 Python3 提交中击败了91.11%的用户
内存消耗 :13.5 MB, 在所有 Python3 提交中击败了5.08%的用户
- 方法二双指针计数方法的实现
1 |
|
时间复杂度:让我们看看最耗时的操作是什么: 我们必须遍历数组中的所有元素,若数组中有 N 个元素,则花费的时间为 \(O(N)\)。删除多余的重复项,del
操作也是 \(O(N)\)。最糟糕的情况是数组中的元素都相同,则我们需要执行 N-1 次的删除操作,则需要花费\(O(N^2)\)。 则,总的复杂度:\(O(N) + O(N^2)\)
空间复杂度:\(O(1)\),我们在原地修改数组。
执行用时 :44 ms, 在所有 Python3 提交中击败了84.12%的用户 内存消耗 :13.4 MB, 在所有 Python3 提交中击败了5.08%的用户
- 方法三双指针覆盖的实现
1 |
|
时间复杂度:\(O(N)\),我们遍历每个数组元素一次。
空间复杂度:\(O(1)\)。
执行用时 :40 ms, 在所有 Python3 提交中击败了91.11%的用户
内存消耗 :13.6 MB, 在所有 Python3 提交中击败了5.08%的用户
参考连接
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!