LeetCode/删除有序数组中的重复项

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

1. 暴力法

从前往后或者从后往前遍历,碰到相同元素,则把后面所有元素前移,覆盖掉该相同元素,时间复杂度为O(n2)

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int n =nums.size();
        for(int i=n-1;i>0;i--){//从后往前
            if(nums[i-1]==nums[i]){
                for(int j = i-1;j<n-1;j++)//注意j的遍历范围,不要使得j+1溢出
                    nums[j] = nums[j+1];
                n--;
            }
        }
        return n;
    }
};

2. 双指针映射

记录一个无重复数组指针位置,记录一个遍历全数组指针,做无重复元素数组到全数组的映射
本质上也是无重复数组的不断扩大

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int n =nums.size();
        //两个指针做映射
        int k = 1;//无重复数组的待插入位置
        for(int i=0;i < n-1;i++){//从前往后
            if(nums[i]==nums[i+1]) continue;//这里可以直接判断相邻两个数,也可以与无重复数组最后一个数比较,都是等价的
            nums[k] = nums[i+1];//nums[i+1]是第一个不重复的数
            k++;
        }
        return k;
    }
};

3. 每个元素可以出现m次

本质上还是已修正数组的扩大,考虑将指针对应数字加入时,判断已修正数组中是否已有m次数,由于是有序的,直接取对应索引值判断即可

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int n =nums.size();
        m = 2;//这里以两次为例
        int k = 0;//已修正数组的待插入位置
        for(int i=0;i < n;i++)//从前往后
            if(i<m||nums[k-m]!=nums[i])//先填充小于2的值,然后判断修正数组中,是否有两个相同值,没有则插入
            nums[k++] = nums[i];
        return k;
    }
};
posted @ 2022-06-26 20:37  失控D大白兔  阅读(30)  评论(0)    收藏  举报