博文中会简要介绍Leetcode P0080题目分析及解题思路。
“Remove Duplicates from Sorted Array II”是一道比较基础的双指针问题,该题是p0026的变形题,考察的主要是双指针移动的边界条件。
Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twice and return the new length.
Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
根据题意不难得出,我们需要一个left
指针用于定位当前right
指针指向的位置上的元素应该出现的地方。这样一来,当right
指针往右移动时,我们每次都将right
指针指向的元素付给left
指针的位置,并且根据情况移动left
指针,从而跳过重复元素的额外副本,以使得所有重复元素有且仅有最多两个副本。
根据上述思路,双指针移动的边界条件如下:
only move right, if n[right] == n[left-1] && dup == 2
如果right指针指向的元素和left指针之前的元素相同,且现有的副本已经有两个了,则跳过该元素,移动right指针。
n[left] = n[right];
move left;
move right;
在其他情况下,将right指针指向的元素赋予left指针指向的位置,从而使得那些被跳过的元素可以被后续的合法元素覆盖。
除此之外,还需要根据情况更新duplicates
计数器,这段逻辑在代码中比较明显,就不再赘述了。
以下是Java的题解代码实现。
class Solution {
public int removeDuplicates(int[] nums) {
if (nums == null || nums.length == 0)
return 0;
int len = 1, duplicates = 1, itr = 1;
while (itr < nums.length) {
if (nums[itr] == nums[len-1]) {
if (duplicates == 2) {
++itr;
continue;
}
else
++duplicates;
}
else
duplicates = 1;
nums[len] = nums[itr];
++len;
++itr;
}
return len;
}
}
以下是C++的题解代码实现。
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if (nums.size() == 0)
return 0;
int left = 1, duplicates = 1, right = 1;
while (right < nums.size()) {
if (nums[right] == nums[left-1]) {
if (duplicates == 2) {
++right;
continue;
}
else
++duplicates;
}
else
duplicates = 1;
nums[left] = nums[right];
++left;
++right;
}
return left;
}
};