• 27. 移除元素


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

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

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

    说明:

    为什么返回数值是整数,但输出的答案是数组呢?

    请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

    你可以想象内部操作如下:

    // nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝 int len = removeElement(nums, val);

    // 在函数里修改输入数组对于调用者是可见的。 // 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。 for
    (int i = 0; i < len; i++) {
    print(nums[i]); }

    示例 1:

    输入:nums = [3,2,2,3], val = 3
    输出:2, nums = [2,2]
    解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
    示例 2:

    输入:nums = [0,1,2,2,3,0,4,2], val = 2
    输出:5, nums = [0,1,4,0,3]
    解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。

    提示:

    0 <= nums.length <= 100
    0 <= nums[i] <= 50
    0 <= val <= 100

    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;
    
            //方法二
             return remove(nums.begin(), nums.end(), val) - nums.begin(); 
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    remove:

    当你调用remove(nums.begin(), nums.end(), val),它实际上并没有真正地删除元素,而是将等于val的元素移到容器的末尾,并返回一个新的迭代器,指向新的末尾位置。这个新的迭代器减去容器的起始迭代器nums.begin()就得到了移除元素的数量,也就是被移到末尾的元素的数量。
    这种设计的目的是为了保持容器的大小不变,但在容器中将特定值移到末尾,以便稍后可以使用erase等操作来实际删除这些元素。所以,通过这种方法,你可以知道有多少个元素被移除,而不会改变容器的大小。

    erase函数:

    当使用C++标准库容器时,erase函数用于从容器中删除元素,它的使用方式取决于容器的类型。一般来说,erase可以这样使用:

    1、删除单个元素:使用迭代器指定要删除的元素。

    container.erase(iterator); // 删除迭代器指向的元素
    删除一个范围:使用迭代器对指定的范围进行删除。

    container.erase(start_iterator, end_iterator); // 删除指定范围内的元素
    以下是几个示例,演示了如何在不同类型的容器中使用erase函数:

    2、对于 std::vector:

    std::vector numbers = {1, 2, 3, 4, 5};

    // 删除第三个元素(索引为2)
    numbers.erase(numbers.begin() + 2);

    // 删除索引2到4之间的元素
    numbers.erase(numbers.begin() + 2, numbers.begin() + 5);

    #include 
    
    using namespace std;
    
    int main(){
        vector<int> v1{ 10, 20, 30, 40, 50 };
        v1.erase(v1.begin() + 1, v1.begin() + 3); //真的是只移除了索引为1,2的元素!
        for (int x:v1)
            cout << x << " ";
        cout << endl;
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3、对于 std::list:

    std::list numbers = {1, 2, 3, 4, 5};

    // 删除第三个元素
    auto it = std::next(numbers.begin(), 2);
    numbers.erase(it);

    // 删除第二到第四个元素
    auto start = std::next(numbers.begin(), 1);
    auto end = std::next(numbers.begin(), 4);
    numbers.erase(start, end);
    4、对于 std::set 和 std::map:

    在 std::set 和 std::map 中,你不能直接删除元素,但你可以使用 erase 函数来删除指定键对应的元素。

    std::set numbers = {1, 2, 3, 4, 5};

    // 删除值为3的元素
    numbers.erase(3);

    std::map myMap = {{1, “one”}, {2, “two”}};

    // 删除键为2的元素
    myMap.erase(2);
    请注意,在使用 erase 函数时,务必小心,确保提供正确的迭代器或键,以避免不必要的错误。

  • 相关阅读:
    uvm核心
    transformer架构中 encoder decoder self-attention cross-attention的作用
    第二十四课、二十五课,高级光照(blinn),Gamma矫正
    05.SpringCloudAlibaba-注册中心Nacos
    LVGL | 1.LVGL PC模拟器之CodeBlocks
    云计算(一):弹性计算概述
    python多线程与多进程
    关于 a (链接)标签 里面包含图片会被撑大的解决方法、a标签会撑大的解决方法
    第十五章 I/O(输入/输出)流
    科普系列:AUTOSAR与OSEK网络管理比较(下)
  • 原文地址:https://blog.csdn.net/qq_45871035/article/details/133324971