26.删除有序数组中的重复项

  1. 26.删除有序数组中的重复项
    1. 26.1 题目
    2. 26.2 题解
      1. 快慢指针
    3. 26.3 代码
    4. 26.4 运行结果

26.删除有序数组中的重复项


26.1 题目

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

要求:

  • 更改数组 nums,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
  • 返回 k

判题标准:

系统会用下面的代码来测试你的题解:

int[] nums = [...]; // 输入数组
int[] expectedNums = [...]; // 长度正确的期望答案

int k = removeDuplicates(nums); // 调用

assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
    assert nums[i] == expectedNums[i];
}

如果所有断言都通过,那么您的题解将被通过。

示例 1:

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

示例 2:

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

提示:

  • 1 <= nums.length <= 3 * 104
  • -104 <= nums[i] <= 104
  • nums 已按非严格递增排列

26.2 题解

快慢指针

// 方法一:快慢指针
// 慢指针记录非重复元素位置和个数 快指针一直往后遍历去发现不同元素
static int RemoveDuplicates(int[] nums)
{
    if (nums.Length <= 1)
    {
        return nums.Length;
    }

    // 初始化两个指针,慢指针和快指针,初始位置都为1
    int slow = 1;
    int fast = 1;

    // 开始循环,直到快指针达到数组的末尾
    while (fast < nums.Length)
    {
        // 检查快指针指向的元素是否与前一个元素相同
        if (nums[fast] != nums[fast - 1])
        {
            // 如果不同,将该元素放入慢指针指向的位置,并将慢指针向前移动
            nums[slow] = nums[fast];
            ++slow;
        }

        // 无论当前元素是否相同,都将快指针向前移动
        ++fast;
    }

    // 返回新数组的长度,即不重复元素的个数
    return slow;
}

26.3 代码

using System;

class Program
{
    static void Main()
    {
        #region 题目

        // 给你一个非严格递增排列的数组 nums,请你原地删除重复出现的元素,使每个元素只出现一次,返回删除后数组的新长度。
        // 元素的相对顺序应该保持一致。然后返回 nums 中唯一元素的个数。
        // 考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:
        // 更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
        // 返回 k。
        // 判题标准:
        // 系统会用下面的代码来测试你的题解:
        // int[] nums = [...]; // 输入数组
        // int[] expectedNums = [...]; // 长度正确的期望答案
        // int k = removeDuplicates(nums); // 调用
        // assert k == expectedNums.length;
        // for (int i = 0; i < k; i++) {
        //     assert nums[i] == expectedNums[i];
        // }

        #endregion

        #region 测试

        // 示例 1
        int[] nums1 = { 1, 1, 2 };
        int[] expectedNums1 = { 1, 2 };
        int k1 = RemoveDuplicates(nums1);
        PrintResult(k1, nums1, expectedNums1);

        // 示例 2
        int[] nums2 = { 0, 0, 1, 1, 1, 2, 2, 3, 3, 4 };
        int[] expectedNums2 = { 0, 1, 2, 3, 4 };
        int k2 = RemoveDuplicates(nums2);
        PrintResult(k2, nums2, expectedNums2);

        #endregion
    }

    #region 答案

    // 方法一:快慢指针
    // 慢指针记录非重复元素位置和个数 快指针一直往后遍历去发现不同元素
    static int RemoveDuplicates(int[] nums)
    {
        if (nums.Length <= 1)
        {
            return nums.Length;
        }

        // 初始化两个指针,慢指针和快指针,初始位置都为1
        int slow = 1;
        int fast = 1;

        // 开始循环,直到快指针达到数组的末尾
        while (fast < nums.Length)
        {
            // 检查快指针指向的元素是否与前一个元素相同
            if (nums[fast] != nums[fast - 1])
            {
                // 如果不同,将该元素放入慢指针指向的位置,并将慢指针向前移动
                nums[slow] = nums[fast];
                ++slow;
            }

            // 无论当前元素是否相同,都将快指针向前移动
            ++fast;
        }

        // 返回新数组的长度,即不重复元素的个数
        return slow;
    }


    static void PrintResult(int k, int[] nums, int[] expectedNums)
    {
        Console.WriteLine($"输出:{k}, nums = [{string.Join(",", nums)}]");
        Console.WriteLine($"期望:nums = [{string.Join(",", expectedNums)}]");
        Console.WriteLine();
    }

    #endregion
}

26.4 运行结果

输出:2, nums = [1,2,2]
期望:nums = [1,2]

输出:5, nums = [0,1,2,3,4,2,2,3,3,4]
期望:nums = [0,1,2,3,4]


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏