27. 移除元素

169 阅读2分钟

27. 移除元素

LeetCode

描述:

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

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

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

示例:

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]

这里观察题目函数的返回值可以看到, 返回值是int, 也就是只需要删除指定元素后的数组长度, 第二个数组的输出不是本函数里的, 但是需要保证数组nums的前n位是删除后的数据, 后面的数据是什么不用关心.

思路:

  • 第一想法就是新建一个数组来做, 但是题目约束了不可以使用其他的数组空间, 所以这个方法不行, 也的确没意义.
  • 这里常用的方法就是双指针法, 这里的指针就是数组的索引值, 使用两个指针来指向数组中的元素, 快指针进行遍历数组, 慢指针进行数组元素的改变操作.
  • 双指针法的具体流程如下(由于无法制作动图故采用文字描述):
    1. 开始的时候, 两个指针指向首元素
    2. 当前元素不是需要删除的元素val, 将快指针指向的元素值赋值给慢指针指向的元素, 之后慢指针slow++, 然后开始下个元素判断即快指针fast++
    3. 若当前元素是要删除的元素, 慢指针不做改动, 直接进入下个元素的判断fast++
    4. 当遍历结束, 直接返回慢指针, 由于有++操作, 所以慢指针(索引值)就是删除指定元素后的长度

代码:(C++)

/*
 * @lc app=leetcode.cn id=27 lang=cpp
 *
 * [27] 移除元素
 */

// @lc code=start
class Solution {
public:
    int removeElement(vector<int>& nums, int val) { 

      int slow{0};
      
      for(int fast = 0; fast < nums.size(); fast++){
        if (nums[fast] != val){
          nums[slow] = nums[fast];
          slow++;
        }
      }

    return slow;

    }
};
  • 时间复杂度:O(n),其中 n 为序列的长度。我们只需要遍历该序列至多两次。
  • 空间复杂度:O(1), 我们只需要常数的空间保存若干变量。