菜菜刷leetcode26、27删除有序数组中的重复项、移除元素

本文介绍了一种使用双指针技术解决数组中重复元素问题的方法。通过快慢两个指针配合,实现原地删除数组中的重复元素或特定值,同时保持元素顺序不变。文章提供了两种双指针解决方案,并附带示例代码。

题目 

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

如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。将最终结果插入 nums 的前 k 个位置后返回 k 。不使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

判题标准:

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

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

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

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

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

从判断方式可以看出,是输入已知的期望答案,将函数调用后的数组与已知答案进行比较是否匹配,且是在原地修改数组,所以函数只需要返回修改后的长度即可

思路

若是没有要求原地修改的话,最简单的思路就是暴力遍历,每经过一个不重复的值就赋到新的数组上,由于原地修改的要求,则用到指针。

且为双指针一个指针(快指针)负责向下走也就是遍历,另一个指针(慢指针)则指向下一个填充的位置,当快指针指向一个与上一个元素不同的数时,将它填充到慢指针所指向的位置即可

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
      int n=nums.size();
      if(n==0)
      {
        return 0;
      }
      int fast=1,slow=1;
      while(fast<n)
      {
         if(nums[fast]!=nums[fast-1])
         {  
             nums[slow]=nums[fast];
             slow++;
         }
         fast++;
      }
      return slow;
    }
};

没有什么需要新学的概念,掌握好双指针的思想就好。。三天做一道题,觉越来越多,好懒。。

补 理解了双指针的思想解决27题就很简单了

题干也对主函数中函数的调用解释了(虽然很明显。。)

按照26的思路直接可码

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
    int slow=0,fast=0;
    int n=nums.size();
    while(fast<n)
    {
        if(nums[fast]!=val)
        {
          nums[slow]=nums[fast];
          slow++;
        }
        fast++;
    }
    return slow;
    }
};
 

题解里还有另一种方法

仍然是双指针,但是一个在最左一个在最右,当左指针指向的数为val时,将右指针所指的数赋给左指针所指的,继续判断,知道两指针相遇。

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int left = 0, right = nums.size();
        while (left < right) {
            if (nums[left] == val) {
                nums[left] = nums[right - 1];
                right--;
            } else {
                left++;
            }
        }
        return left;
    }
};
载请注明出处。

嗯。。 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值