力扣26题-删除有序数组中的重复项

一,题目

给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。

考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:

  • 更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
  • 返回 k 。

二,思路

  1. 理解问题:

    • 目标是从一个非严格递增排列的数组 nums 中删除重复的元素,使每个元素只出现一次,并保持原有的相对顺序。
    • 最后需要返回新数组中唯一元素的个数 k
  2. 原地修改:

    • 要求在原数组上进行修改,不允许使用额外的数组来存储结果。
    • 这样可以节省空间,符合题目的要求。
  3. 使用双指针:

    • 一个指针i)用于遍历整个数组。
    • 另一个指针k)用于记录唯一元素在数组中的位置。
  4. 遍历数组:

    • 遍历整个 nums 数组,检查当前元素 nums[i] 是否与前一个元素 nums[k-1] 相同。
    • 如果不同,说明是一个新的唯一元素,将其放在 nums[k] 的位置,并增加 k
  5. 返回结果:

    • 遍历结束后,k 的值就是数组中唯一元素的数量,同时前 k 个元素就是去重后的结果。

三,复杂度分析

时间复杂度

  1. 遍历数组:

    • 函数中使用了一个 for 循环来遍历整个数组 nums。这个循环从索引 1 到 n-1(其中 n 是数组的长度),因此时间复杂度为 O(n),因为每个元素都被访问了一次。
  2. 条件判断和赋值:

    • 在循环内部,对于每个元素,我们进行常数时间的条件判断和赋值操作(将新找到的唯一元素放在 nums[k] 的位置)。这些操作的时间复杂度都是 O(1)。

总体时间复杂度

  • 因此,整体的时间复杂度为 O(n),这是处理这个问题时的最优复杂度,因为我们必须遍历整个数组。

空间复杂度

  1. 原地修改:

    • 这个实现是原地的,意味着我们没有使用额外的数组来存储结果,而是直接在 nums 数组上进行修改。
  2. 常数空间:

    • 只使用了几个额外的变量(如 k 和循环变量 i),这些都占用常数空间,不依赖于输入数据的大小。

总体空间复杂度

  • 因此,空间复杂度为 O(1),表示只使用了常数级别的额外空间。

总结

  • 时间复杂度: O(n) — 遍历整个数组的时间。
  • 空间复杂度: O(1) — 只使用了常数级别的额外空间。

代码:

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int k=1;//记录不重复元素的个数
        for(int i=0;i<nums.size();i++){
            if(nums[i]!=nums[k-1]){
                nums[k]=nums[i];
                k++;
            }
        }
        return k;
    }
};

四,子题:力扣80

题目描述:

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

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

实现:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值