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 小时前
(LeetCode 面试经典 150 题 ) 11. 盛最多水的容器 (贪心+双指针)
java·c++·算法·leetcode·面试·go
chao_7891 小时前
二分查找篇——搜索旋转排序数组【LeetCode】两次二分查找
开发语言·数据结构·python·算法·leetcode
3Katrina2 小时前
深入理解 useLayoutEffect:解决 UI "闪烁"问题的利器
前端·javascript·面试
秋说3 小时前
【PTA数据结构 | C语言版】一元多项式求导
c语言·数据结构·算法
Maybyy3 小时前
力扣61.旋转链表
算法·leetcode·链表
卡卡卡卡罗特5 小时前
每日mysql
数据结构·算法
chao_7896 小时前
二分查找篇——搜索旋转排序数组【LeetCode】一次二分查找
数据结构·python·算法·leetcode·二分查找
lifallen6 小时前
Paimon 原子提交实现
java·大数据·数据结构·数据库·后端·算法
天天扭码6 小时前
很全面的前端面试——CSS篇(上)
前端·css·面试
lixzest6 小时前
C++ Lambda 表达式详解
服务器·开发语言·c++·算法