删除有序数组中的重复项 II

691 阅读3分钟

这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战

leetcode 删除有序数组中的重复项 II

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

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

示例 1:

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

示例 2:

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

解题: 要原地删除数组元素,其实也不是要真的删除掉数组里重复的元素,只需要把所有有序不重复的都移动到数组的最左端,数组后面一部分元素还是存在的,只需要返回前面一部分的数量,后面的元素情况不用管,因此只要想办法,找出数组内所有不重复的元素,依次把它们从左到右排列再数组左端就可以了。但是题目数组有序情况下的重复元素可以最多出现两次,而不是只保留一位的,所以是有两个以上的重复元素才需要删除其余的元素。因为数组已经是有序的,所以重复元素必定是相邻的了,那么可以使用双指针来遍历数组元素,如果元素没有超过两个重复存在的就应该保留,移动到指定位置,否则元素超过两个重复的了,那就说明是需要删除的了。具体的可以定义两个指针slowfast分别为慢指针和快指针,慢指针表示应该要处理的数组长度,快指针表示已经处理的数组长度,指针slowfast双指针的初始值设置为2即可,因为对于长度小于等于2的数组是不用处理的了。题目要求重复元素最多出现两个,所以我们可以判断当前元素nums[fast]是否和上上一个元素nums[slow - 2]相同,当nums[fast] = nums[slow - 2]时,那么说明当前元素是不要被保留的,所以nums[slow - 2]=nums[slow - 1]=nums[fast],最后再返回slow即可,就是符合条件的数组元素大小了。

class Solution {
    public int removeDuplicates(int[] nums) {
        int len = nums.length;
        if (len <= 2) {
            return len;
        }
        int slow = 2;
        int fast = 2;
        while (fast < len) {
            if (nums[slow - 2] != nums[fast]) {
                nums[slow] = nums[fast];
                slow++;
            }
            fast++;
        }
        return slow;
    }
}