zoukankan      html  css  js  c++  java
  • 26. 删除排序数组中的重复项 27. 移除元素 双指针

    题目:

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

      不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 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。

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

    解答:

    首先是自己的解答:

      根据提示,使用双指针,也叫快慢指针,index1从首部移动, index2向后移动直到值与index1不同,则将 index2及之后的元素移动到index1+1的位置,重复直至index2抵达末位,然后返回的长度为:index1+1,因为index1是索引,比当前不重复元素少一。

      代码如下:

    //26. 删除排序数组中的重复项
    //原地删除重复元素,并且返回结果的长度int
    //双指针
    int removeDuplicates(vector<int>& nums) 
    {
        if (nums.size() < 2)
            return nums.size();
    
        //排序
        sort(nums.begin(), nums.begin() + nums.size());
    
        int idx1 = 0, idx2 = 1;
        while (idx2 < nums.size())
        {
            while (idx2 < nums.size() && nums[idx1] == nums[idx2])
                idx2++;
            if (idx2 == nums.size())
                return idx1 + 1;
    
            for (int i = idx1+1; i < idx2; i++)
            {
                nums[i] = nums[idx2];
            }
    
            //test
            for (auto val : nums)
            {
                cout << val << "	";
            }
            cout << endl;
    
            idx1++;
            idx2++;
        }
    
        return idx1 + 1;
    }

      虽然提交后通过了,但是时间、空间效率很差。

      看解答后,发现只要把index2处不重复的元素复制到index1+1即可,减少元素的移动次数,代码如下:

    int removeDuplicates(vector<int>& nums) {
            if (nums.size() < 2)
                return nums.size();
    
            //sort
            sort(nums.begin(), nums.begin() + nums.size());
    
            int idx1 = 0, idx2 = 1;
            while (idx2 < nums.size())
            {
                if (nums.at(idx1) != nums.at(idx2))
                {
                    //如果不等,把idx2的元素放到idx1++的位置
                    idx1++;
                    nums[idx1] = nums[idx2];
                }
                    
                //如果idx2 与 idx1 相等,则j++
                idx2++;
            }
    
            return idx1 + 1;
        }

    小结:

      刷题后,多看题解,最好敲一遍学习学习。

     题目27:

    给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

    不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

    元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

    示例 1:

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

    函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。

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

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

    函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。

    注意这五个元素可为任意顺序。

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

    解答:

    27题与26题类似,放到一起写。先自己写的代码,使用两个index在数组中移动,index找到第一个==val的值,然后index2找到后面不等于val的值,然后使用一个变量交换这两个位置的值“:

    int removeElement(vector<int>& nums, int val) {
            if (nums.size() == 0)
                return 0;
            else if (nums.size() == 1 && nums[0] != val)
                return nums.size();
    
            int idx1 = 0, idx2 = 1;
            int tmp = 0;
            while (idx2 < nums.size())
            {
                while (idx1 < nums.size() && nums[idx1] != val)
                {
                    idx1++;
                    idx2++;
                }
                    
                if (idx1 == nums.size() || idx2 >= nums.size())
                    break;
    
                if (nums[idx2] == val)
                {
                    idx2++;
                    continue;
                }
                
                //此时,idx1=val,idx2++找到一个不等的元素
                tmp = nums[idx2];
                nums[idx2] = nums[idx1];
                nums[idx1] = tmp;
                idx1++;
                idx2 = idx1 + 1;
            }
    
            return idx1;
        }

    解答的代码:真tm简洁,自己写的就是一坨,解答中的代码可以在num[i]=num[j]之前加个判断,当i == j时赋值这步可以跳过,减少操作。

    public int removeElement(int[] nums, int val) {
        int i = 0;
        for (int j = 0; j < nums.length; j++) {
            if (nums[j] != val) {
                nums[i] = nums[j];
                i++;
            }
        }
        return i;
    }
  • 相关阅读:
    Rails生成随机字符串及加解密
    rails generate model/resource/scaffold的区别
    Rails generate的时候不生成assets和test
    rails delegate机制
    React Router V4发布
    react中创建组件的三种方法
    fetch的用法
    Ruby中map, collect,each,select,reject,reduce的区别
    Sublime Theme
    CentOS 升级Python3.X和pip3
  • 原文地址:https://www.cnblogs.com/zyk1113/p/14001571.html
Copyright © 2011-2022 走看看