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;
}
相关推荐
菜鸟233号5 小时前
力扣347. 前k个高频元素 java实现
算法
Xの哲學6 小时前
Linux设备管理:从内核驱动到用户空间的完整架构解析
linux·服务器·算法·架构·边缘计算
Query*6 小时前
杭州2024.08 Java开发岗面试题分类整理【附面试技巧】
java·开发语言·面试
xinyu_Jina7 小时前
Info Flow:去中心化数据流、跨协议标准化与信息源权重算法
算法·去中心化·区块链
Jac_kie_層樓7 小时前
力扣hot100刷题记录(12.2)
算法·leetcode·职场和发展
有意义7 小时前
this 不是你想的 this:从作用域迷失到调用栈掌控
javascript·面试·ecmascript 6
稚辉君.MCA_P8_Java7 小时前
Gemini永久会员 C++返回最长有效子串长度
开发语言·数据结构·c++·后端·算法
风止何安啊8 小时前
别被 JS 骗了!终极指南:JS 类型转换真相大揭秘
前端·javascript·面试
over6978 小时前
深入理解 JavaScript 原型链与继承机制:从 instanceof 到多种继承模式
前端·javascript·面试
京东零售技术8 小时前
下一代 Lakehouse 智能未来新引擎 | Apache Hudi Meetup亚洲站活动回顾
算法