80. Remove Duplicates from Sorted Array II

题目描述和难度

  • 题目描述:

给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。

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

示例 1:

给定 nums = [1,1,1,2,2,3],

函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。

你不需要考虑数组中超出新长度后面的元素。

示例 2:

给定 nums = [0,0,1,1,1,1,2,3,3],

函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。

你不需要考虑数组中超出新长度后面的元素。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

思路分析

求解关键:

分类讨论,临界值判断。

参考解答

参考解答1

Java 写法:

import java.util.Arrays;

// https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii/description/
// 每个元素至多出现 2 次
// 解释:删除重复的元素,但是要求重复的元素至多保留两个。
// 思考:应该充分利用排好序的数组这个特性来完成。
// 设置一个变量,用于比较和之前的值是否重复,还要设置一个变量,计算重复次数。
// 注意:同样要注意到 nums = [] 的情况。
// 这道题调试了很久,最终还是独立解出来了,
// 主要是忽略了一个细节,在重复次数为 1 的时候,挪动指针位置的时候,同时也要赋值,一开始我忘记赋值了。

public class Solution {


    // 重复出现 1 次和 2 次的时候什么都不做
    // [0,1,1,1,2,2,2,2,3,3,4]

    public int removeDuplicates(int[] nums) {
        // [1,1] 最多 2 个元素就能够不用判断
        int len = nums.length;

        if (len <= 2) {
            return len;
        }
        int pre = nums[0];
        int duplicateTimes = 0;

        // 第 1 个元素肯定被保留,所以直接写 1
        // j 表示我每一次遍历,即将被覆盖的那个索引
        int j = 1;
        for (int i = 1; i < len; i++) {
            if (nums[i] == pre) {
                // 只要有重复,次数就要加 1
                duplicateTimes++;
                // 重复 1 次的时候,也要赋值
                if (duplicateTimes == 1) {
                    nums[j] = pre;
                    j++;
                }
                // 重复 1 次以上的时候,什么都不做,就相当于没有看到这个元素
            } else {
                // 重置次数和之前的那个值
                pre = nums[i];
                duplicateTimes = 0;

                nums[j] = nums[i];
                j++;
            }
        }
        return j;
    }

    public static void main(String[] args) {
        int[] nums = {0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4};
        int ret = new Solution().removeDuplicates(nums);
        System.out.println(ret);
        System.out.println(Arrays.toString(nums));
    }
}

Python 写法:

class Solution:
    def rotate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: void Do not return anything, modify nums in-place instead.
        """

        # 先处理极端情况

        if len(nums) == 0 or k <= 0:
            return

        k = k % len(nums)

        # 做下面 3 个逆转动作的时候,注意边界条件
        # 技巧就是举具体的例子
        self.__reverse(nums, 0, len(nums) - 1)
        self.__reverse(nums, 0, k - 1)
        self.__reverse(nums, k, len(nums) - 1)

    def __reverse(self, nums, index1, index2):
        """
        将数组 [index1,index2] 区间内的元素进行逆转
        :param nums:
        :param index1:
        :param index2:
        :return:
        """

        while index1 < index2:
            nums[index1], nums[index2] = nums[index2], nums[index1]
            index1 += 1
            index2 -= 1


if __name__ == '__main__':
    nums = [1, 2, 3, 4, 5, 6, 7]
    k = 3

    s = Solution()
    s.rotate(nums, k)
    print(nums)

本篇文章的地址为 https://liweiwei1419.github.io/leetcode-solution/leetcode-0080-remove-duplicates-from-sorted-array-ii ,如果我的题解有错误,或者您有更好的解法,欢迎您告诉我 liweiwei1419@gmail.com