zoukankan      html  css  js  c++  java
  • LeetCode#26-Remove Duplicates from Sorted Array-删除有序数组中的重复元素

    一、题目

    给定一个排序数组,在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
    不要使用额外的数组空间,必须在原地修改输入数组,并使用 O(1) 额外空间来修改输入的数组。
    示例1:

    给定数组 nums = [1,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。
    
    你不需要考虑数组中超出新长度后面的元素。
    

    第一个示例中,函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。
    第二个示例中,函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
    这里不需要考虑数组中超出新长度后面的元素。

    二、题解

    • 首先,题目规定了空间复杂度是O(1),对时间复杂度没做要求,当然了,我们解题还是要追求一下更小的时间复杂度,能O(n)就不O(n²),能O(logn)就不O(n)。

    • 其次,题目给出数组已经排好序了,当数组为空或只有1个元素时,肯定没有重复项,直接返回数组长度即可;只有当数组中的元素大于3个,才可能出现重复项。

    • 第三,要修改给定的数组,而不是返回一个新数组,我想到了PHP中的“引用传递”,修改数组中的某个元素,整个数组也会变化。

    我首先想到的做法是:遍历数组,将当前元素和下一个元素进行比较,如果相同,就删除当前元素,直到遍历到末尾。代码如下:

    function removeDuplicates(&$nums) {
        if (count($nums) <= 2) {
            return count($nums);
        }
    
        for ($i = 0; $i < count($nums) - 1; $i++) {
            if ($nums[$i] == $nums[$i + 1]) {
                unset($nums[$i]);
            }
            echo count($nums) . "<br>";
        }
        return count($nums);
    }
    

    提交代码未通过。输入的是[0,0,1,1,1,2,2,3,3,4],可输出的是[0,1,2,3,3,4],并没有完成去重。琢磨了一下代码,发现漏洞:既然是引用传递,每 unset 一个元素,都会改变数组的长度,而随着数组长度的缩短,遍历次数也会跟着改变(减少),后面的元素就不再进行比较、删除了。

    那就记录遍历时遇到的重复元素,使用两个指针,一快一慢指针,慢指针 i 记录不重复元素,快指针 j 遍历数组,当(nums[i] != nums[j])时,将慢指针右移一位,同时将快指针指向的元素赋值给当前慢指针;当两者相等时则跳过,即双指针法

    function removeDuplicates(&$nums) {
        if (count($nums) <= 1) {
            return count($nums);
        }
    
        $i = 0;
        for ($j = 1; $j < count($nums); $j++) {
            if ($nums[$i] == $nums[$j]) {
                continue;
            }
            $i++;
            $nums[$i] = $nums[$j];
        }
        return count(array_slice($nums, 0, $i + 1));
    }
    
  • 相关阅读:
    多线程中变量的内存分配
    VS2019解决Cannot resolve symbol ' '问题
    排序算法——选择排序
    观察者模式
    c# 之linq——小白入门级
    c# 迭代器
    MySql学习
    rabbitmq安装及简单demo练习
    VMware Workstation 12 PRo密钥
    远程过程调用——RPC
  • 原文地址:https://www.cnblogs.com/sunshineliulu/p/12322193.html
Copyright © 2011-2022 走看看