leetcode 面试经典 150 题:移除元素

链接 移除元素
题序号 27
类型 数组
解题方法 双指针
难度 简单

题目

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。

假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作:

更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。nums 的其余元素和 nums 的大小并不重要。 返回k。

  • 用户评测

    评测机将使用以下代码测试您的解决方案:

    int[] nums = [...]; // 输入数组

    int val = ...; // 要移除的值

    int[] expectedNums = [...]; // 长度正确的预期答案。 // 它以不等于 val 的值排序。

    int k = removeElement(nums, val); // 调用你的实现

    assert k == expectedNums.length; sort(nums, 0, k); // 排序 nums 的前 k 个元素

    for (int i = 0; i < actualLength; i++) {

    assert nums[i] == expectedNums[i];

    }

    如果所有的断言都通过,你的解决方案将会 通过。

  • 示例 1

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

    解释:你的函数函数应该返回 k = 2, 并且 nums 中的前两个元素均为 2。 你在返回的 k 个元素之外留下了什么并不重要(因此它们并不计入评测)。

  • 示例 2

    输入:nums = [0,1,2,2,3,0,4,2], val = 2 输出:5, nums = [0,1,4,0,3,, ,_]

    解释:你的函数应该返回 k = 5,并且 nums 中的前五个元素为 0,0,1,3,4。 注意这五个元素可以任意顺序返回。 你在返回的 k 个元素之外留下了什么并不重要(因此它们并不计入评测)。

  • 提示

    0 <= nums.length <= 100

    0 <= nums[i] <= 50

    0 <= val <= 100

题解

双指针法

  1. 要点:一个指针 right 用于遍历数组,另一个指针 left 用于指向下一个不等于 val 的元素应该放置的位置。
  2. 时间复杂度:O(n);
  3. 空间复杂度:O(1);
  4. c++ 算法:
cpp 复制代码
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int n = nums.size();
        int left = 0;
        
        for (int right = 0; right < n; right++) {
            if (nums[right] != val) {
                nums[left] = nums[right];
                left++;
            }
        }

        nums.resize(left); //调整 nums 大小
        return left;
    }
};
  1. 演示:以示例1为例
bash 复制代码
推演:
nums = 3 2 2 3
val = 3

removeElement:
    n = nums.size = 4
    left = 0
    for right=0; right<4; right++
        if nums[0] != 3 //等于3,if不成立

    for right=1; right<4; right++
        if nums[1] != 3
            nums[0] = nums[1] = 2
            left++ 等于1
    for right=2; right<4; right++
        if nums[2] != 3 
            nums[1] = nums[2] = 2
            left++ 等于2
    for right=3; right<4; right++
        if nums[3] != 3 //等于3,if不成立
    for right=4; right<4; right++ //for循环不成立,退出

    nums.resize(left) //调整nums大小为left
    return left //返回 

c++ 完整demo

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>

using namespace std;

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

        nums.resize(left); //调整 nums 大小
        return left;
    }
};
int main(){

    vector<int> nums = {3, 2, 2, 3};
    int val = 3;

    Solution solution;

    int number = solution.removeElement(nums, val);

    assert(number == nums.size());

    cout << "number: " << number << endl;

    cout << "nums.size: " << nums.size() << endl;

    for(int i = 0; i< number; i++){
        cout << "i: " << i  << ", nums[" << i << "]: "<< nums[i] << endl;
    }


    return 0;
}
相关推荐
范纹杉想快点毕业1 分钟前
嵌入式系统架构之道:告别“意大利面条”,拥抱状态机与事件驱动
java·开发语言·c++·嵌入式硬件·算法·架构·mfc
近津薪荼5 分钟前
递归专题(4)——两两交换链表中的节点
数据结构·c++·学习·算法·链表
2501_940315266 分钟前
【无标题】2390:从字符串中移除*
java·开发语言·算法
乐观勇敢坚强的老彭8 分钟前
c++寒假营day01下午
c++·算法
散峰而望18 分钟前
【算法竞赛】树
java·数据结构·c++·算法·leetcode·贪心算法·推荐算法
鱼很腾apoc21 分钟前
【实战篇】 第14期 算法竞赛_数据结构超详解(下)
c语言·开发语言·数据结构·学习·算法·青少年编程
123_不打狼34 分钟前
AE(自编码器)与 VAE(变分自编码器)核心区别:原理、目标与应用
深度学习·算法·机器学习·vae
Anastasiozzzz37 分钟前
LeetCode hot100 45 跳跃游戏2
算法·leetcode·游戏
近津薪荼38 分钟前
递归专题(3)——反转链表
数据结构·c++·学习·算法·链表
Tisfy41 分钟前
LeetCode 3013.将数组分成最小总代价的子数组 II:两个堆维护k-1小 + 滑动窗口
算法·leetcode·题解·优先队列··有序集合·滑动窗口