【算法】数组:删除排序数组中的重复项

214 阅读2分钟

题目:删除排序数组中的重复项

leetcode链接:数组-删除排序数组中的重复项

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

由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。

将最终结果插入 nums 的前 k 个位置后返回 k 。

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

理解:

1、将提供一个升序数组nums:说明即使有重复元素彼此也是相邻的。

2、原地删除数组中重复的元素:说明不能使用临时表来存储非重复元素。

3、返回删除重复元素后的数组长度:return 处理过后nums数组的length。

4、空间复杂度为O(1)

大致思路:

1、由于要求原地删除,那么可以利用数组的删除API及下标来完成

2、统计不重复元素的个数

3、不删除元素,但可以替换掉重复元素

题解:

1、方案一:删除数组重复元素

/**
 * @param {number[]} nums
 * @return {number}
 */
var removeDuplicates = function(nums) {
    for (var i = 0; i < nums.length;i++) {
        if (nums[i] === nums[i+1]) {
            // 删除重复元素
            nums.splice(i, 1)
            // 由于删除了重复元素,数组长度减了1,因此数组下标需同步减1
            i--
        }
    }
    return nums.length
}

2、方案二:双指针法

/**
 * @param {number[]} nums
 * @return {number}
 */
var removeDuplicates = function(nums) {
    const n = nums.length;
        if (n == 0) {
            return 0;
        }
        let fast = 1, slow = 1;
        while (fast < n) {
            // 比较前后元素是否重复
            if (nums[fast] != nums[fast - 1]) {
                // 不重复时,将快指针的元素赋值给慢指针指定的元素
                nums[slow] = nums[fast];
                // 慢指针下标+1
                ++slow;
            }
            // 无论是否重复,只要fast < n,则继续完成数组元素的循环,
            ++fast;
        }
        // 最终返回慢指针的下标,即为去重后数组的长度
        return slow;
}

3、方案三:确保前K个结果不重复

/**
 * @param {number[]} nums
 * @return {number}
 */
var removeDuplicates = function(nums) {
    let org = 0;
        for(let now = 1;now < nums.length; now++){
            if(nums[org] != nums[now]){
                nums[++org] = nums[now];
            }
        }
        return !nums.length ? 0 : org+1;
}

说明

上面三个方案是按照执行时间由长到短来排的,或许还有更多更优的解体方案,但时间有限就先整理这么多了