• leetcode 26. 删除有序数组中的重复项


    给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。

    不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

    说明:

    为什么返回数值是整数,但输出的答案是数组呢?

    请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

    你可以想象内部操作如下:

    // nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
    int len = removeDuplicates(nums);
    
    // 在函数里修改输入数组对于调用者是可见的。
    // 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
    for (int i = 0; i < len; i++) {
        print(nums[i]);
    }
    
     

    示例 1:

    输入:nums = [1,1,2]
    输出:2, nums = [1,2]
    解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 不需要考虑数组中超出新长度后面的元素。
    

    示例 2:

    输入:nums = [0,0,1,1,1,2,2,3,3,4]
    输出:5, nums = [0,1,2,3,4]
    解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
    

    提示:

    • 0 <= nums.length <= 3 * 104
    • -104 <= nums[i] <= 104
    • nums 已按升序排列

    法一: 不讲武德,标准库版本

    class Solution {
    public:
        int removeDuplicates(vector<int>& nums) {
            auto iter = unique(nums.begin(), nums.end());
            nums.erase(iter, nums.end());
            return nums.size();
        }
    };

    法二:乱写的迭代器

    class Solution {
    public:
        int removeDuplicates(vector<int>& nums) {
            int len = nums.size();
            if(len == 0) return 0;
            for(vector<int>::iterator it = nums.begin()+1; it!=nums.end(); ){
                if(*it == *(it-1)){
                    nums.erase(it);
                }
                else{
                    ++it;
                }
            }
            return nums.size();
        }
    };

    法三:自己写的双指针

    class Solution {
    public:
        int removeDuplicates(vector<int>& nums) {
            int len = nums.size(), k = 0;
            if(len == 0) return 0;
            for(int i=1; i<len;i++){
                if(nums[i] != nums[k]){
                    nums[++k] = nums[i];
                }
            }
            //if()
            return k+1;
        }
    };

    法三:官方题解的双指针

    class Solution {
    public:
        int removeDuplicates(vector<int>& nums) {
            int len = nums.size();
            if(len == 0) return 0;
    
            int slow = 1, fast = 1;
            while(fast < len){
                if(nums[fast]!=nums[slow-1]){///nums[fast] != nums[fast-1]
                    nums[slow++] = nums[fast];
                }
                fast++;
            }
            return slow;
        }
    };

    • 时间复杂度:O(n),其中 n 是数组的长度。快指针和慢指针最多各移动 n 次。

    • 空间复杂度:O(1)。只需要使用常数的额外空间。

    总结:双指针命名还是不规范,不要用i,j,k。要用slow, fast.

  • 相关阅读:
    loj6033.「雅礼集训 2017 Day2」棋盘游戏
    loj6032. 「雅礼集训 2017 Day2」水箱
    BZOJ 5217 [Lydsy2017省队十连测] 航海舰队
    P4173 残缺的字符串
    P3723 [AH2017/HNOI2017]礼物
    P3321 [SDOI2015]序列统计
    P4841 [集训队作业2013]城市规划
    MySQL基础
    MySQL查询
    HTTP响应码
  • 原文地址:https://www.cnblogs.com/AbsolutelyPerfect/p/14674527.html
Copyright © 2020-2023  润新知