返回

比肩双手快,理解才能提升——数组「1」删除排序数组中的重复项|算法打卡

见解分享

准备面试嘛,算法是我们绕不过去的一个点,正好掘金上有算法打卡活动,就报名参加,同时也督促自己一下。我打算从简单的题开始,逐步深入,这也是我第一次写解题思路,不足之处,还请大佬们多多包涵。

今天我们来做做这道题:数组「1」删除排序数组中的重复项。

题目如下:

给定一个排序数组 nums,请你移除其中重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用后返回新的数组长度。

解题思路

本题方法主要有两种:

  1. 使用双指针法:

    这种方法利用了数组已经排序的特性,使用两个指针 i 和 j 来遍历数组。指针 i 用于指向当前要检查的元素,指针 j 用于指向不重复元素的下一个位置。当我们找到一个与前一个元素不同的元素时,我们将该元素放在 j 指向的位置,然后将 j 指针向右移动一位。

    int removeDuplicates(int* nums, int numsSize) {
        if (numsSize == 0) {
            return 0;
        }
    
        int i = 0;
        int j = 1;
    
        while (j < numsSize) {
            if (nums[j] != nums[i]) {
                nums[i + 1] = nums[j];
                i++;
            }
            j++;
        }
    
        return i + 1;
    }
    
  2. 使用 set 数据结构:

    我们可以使用 set 数据结构来存储数组中的元素,由于 set 中的元素都是唯一的,因此我们可以通过将数组中的元素插入 set 中来去除重复元素。最后,我们将 set 中的元素拷贝回数组中即可。

    int removeDuplicates(int* nums, int numsSize) {
        std::set<int> unique_nums;
    
        for (int i = 0; i < numsSize; i++) {
            unique_nums.insert(nums[i]);
        }
    
        int i = 0;
    
        for (auto it = unique_nums.begin(); it != unique_nums.end(); it++) {
            nums[i++] = *it;
        }
    
        return i;
    }
    

第一种方法更简单易懂,第二种方法更通用,可以用于处理各种需要去重的数据。

时间复杂度:

这两种方法的时间复杂度都是 O(n),其中 n 是数组的长度。

空间复杂度:

第一种方法的空间复杂度是 O(1),第二种方法的空间复杂度是 O(n)。