LeetCode-80. Remove Duplicates in Sorted Array II

description

Given an ascending array nums, you need to delete the repeated elements in place, so that each element appears twice at most, and return the new length of the removed array.

Don't use extra array space, you must modify the input array in-situ and complete with O(1) extra space.

 

Description:

Why is the return value an integer, but the output answer is an array?

Please note that the input array is passed by "reference", which means that modifying the input array in the function is visible to the caller.

You can imagine the internal operation as follows:

// nums is passed by "reference". In other words, do not make any copy of the actual parameters
int len ​​= removeDuplicates(nums);

// Modifying the input array in the function is visible to the caller.
// According to the length returned by your function, it will print out all the elements in the array within that length.
for (int i = 0; i <len; i++) {     print(nums[i]); }


 

Example 1:

Input: nums = [1,1,1,2,2,3]
Output: 5, nums = [1,1,2,2,3]
Explanation: The function should return the new length length = 5, and the front of the original array The five elements have been modified to 1, 1, 2, 2, 3. You don't need to consider the elements in the array beyond the new length.
Example 2:

Input: nums = [0,0,1,1,1,1,2,3,3]
Output: 7, nums = [0,0,1,1,2,3,3]
Explanation: The function should return new Length = 7, and the first five elements of the original array are modified to 0, 0, 1, 1, 2, 3, 3. You don't need to consider the elements in the array beyond the new length.
 

prompt:

0 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
nums in increasing order

Source: LeetCode
Link: https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii/

 

Solve

   class Solution {
    public:
        // 第一版,暴力解法,直接遍历元素发现多余2个的直接调用vector接口erase删除
        // 这个办法非常不好,每次删除会导致删除点后面的所有元素都前移拷贝
        int removeDuplicates_1e(vector<int> &nums) {
            const int n = 2; // 最多保留2个重复元素
            int current = nums[0];
            int i = 0;
            int curNum = 0;
            while (i < nums.size()) {
                if (nums[i] == current) {
                    ++curNum;
                    ++i;
                    continue;
                }
                // 出现新元素
                current = nums[i];
                if (curNum > n) {
                    int extraTwoNum = curNum - n; // 超出2的重复数量
                    nums.erase(nums.begin() + i - extraTwoNum, nums.begin() + i); // 删除元素
                    i -= extraTwoNum; // 删除extraTwoNum个元素后,i下标需要前移extraTwoNum位置
                }
                curNum = 1;
                ++i;
            }
            // 处理如[...., x, x, x, x]的场景
            if (curNum > n) {
                int extraTwoNum = curNum - n; // 超出2的重复数量
                nums.erase(nums.begin() + i - extraTwoNum, nums.begin() + i); // 删除元素
            }
            return nums.size();
        }

        // 第二版,使用辅助空间,空间复杂度O(N),不符合题意
        int removeDuplicates_2e(vector<int> &nums) {
            const int n = nums.size();
            if (nums.size() < 3) {
                return n;
            }
            vector<int> rec;
            rec.reserve(n);
            int cnt = 1;
            int cur = nums[0];
            rec.push_back(nums[0]);
            for (int i = 1; i < n; ++i) {
                if (nums[i] == cur) {
                    if (cnt < 2) {
                        rec.push_back(nums[i]);
                        ++cnt;
                    }
                } else {
                    rec.push_back(nums[i]);
                    cur = nums[i];
                    cnt = 1;
                }
            }
            nums.assign(rec.cbegin(), rec.cend());
            return rec.size();
        }

        // 第三版,双指针,原地处理,空间复杂度O(1)
        int removeDuplicates(vector<int> &nums) {
            const int n = nums.size();
            if (nums.size() < 3) {
                return n;
            }
            int k = 0; // [0...k]保留满足条件的元素
            int cnt = 1;  // 初始情况下已经有一个元素了
            for (int i = 1; i < n; ++i) {
                if (nums[i] == nums[k]) {
                    if (cnt < 2) {
                        nums[++k] = nums[i];
                        ++cnt;
                    }
                } else {
                    nums[++k] = nums[i];
                    cnt = 1;
                }
            }
            return k + 1;
        }
    };

 

 

Guess you like

Origin blog.csdn.net/u010323563/article/details/112436232