首页 > 其他分享 >27.移除元素

27.移除元素

时间:2023-10-25 13:25:32浏览次数:29  
标签:27 val nums int 元素 数组 移除 指针

1.题目介绍

给你一个数组 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

2.题解

2.1 利用函数erase

C++ 标准库的 std::vector(动态数组)中有一个 erase 函数,用于从数组中删除一个或多个元素。以下是 std::vector 的 erase 函数的常见用法:

vector.erase(iterator); // 删除单个元素
vector.erase(iterator1, iterator2); // 删除范围内的元素

代码

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        for (int i = 0; i < nums.size();){
            if (nums[i] == val)
                nums.erase(nums.begin() + i);
            else i++;
        }
        return nums.size();
    }
};

2.2 双指针

本题如果从算法角度来说,其实上是想让我们手动实现erase函数的功能,这里使用双指针就是一个很好的选择。
由于新数组长度肯定是小于旧数组,所以我们可以使用快慢指针的方法,慢指针指向新数组元素的位置,快指针指向旧数组元素位置。若是元素值不等于val,将快指针指向元素赋值给慢指针所在位置后,快慢指针同时推进;反之,慢指针不动,快指针向后推进一个。(有一个问题就是在前面元素均不等于val时,进行了多次重复赋值)

  • 如果右指针指向的元素不等于 \(\textit{val}\),它一定是输出数组的一个元素,我们就将右指针指向的元素复制到左指针位置,然后将左右指针同时右移;

  • 如果右指针指向的元素等于 \(\textit{val}\),它不能在输出数组里,此时左指针不动,右指针右移一位。

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

2.3 优化

思路

在上面讲解思路的时候说过,使用上述快慢指针的方法,会导致需要保留的元素的重复赋值操作(比如像[1,2,3,4,5]中删除5,前面就行了nums[0] = nums[0] ... nums[3] = nums[3] 共四次重复操作),导致时间浪费。
同时我们注意到题目说「元素的顺序可以改变],这里采用首尾指针的方法,可以简化操作。

如果左指针 left 指向的元素等于 val,此时将右指针 right 指向的元素复制到左指针 left 的位置,然后右指针 right 左移一位。如果赋值过来的元素恰好也等于 val,可以继续把右指针 right 指向的元素的值赋值过来(左指针) left 指向的等于 val 的元素的位置继续被覆盖),直到左指针指向的元素的值不等于 val 为止。

当左指针 left 和右指针 right 重合的时候,左右指针遍历完数组中所有的元素。

代码

这里解释一下

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        // int left = 0, right = nums.size() - 1;
        int left = 0, right = nums.size();
        // while (left < right){
        while (left < right){
            if (nums[left] == val){
                nums[left] = nums[right-1];
                right --;
            } else{
                left++;
            }
        }
        return left;
    }
};

标签:27,val,nums,int,元素,数组,移除,指针
From: https://www.cnblogs.com/trmbh12/p/17786922.html

相关文章

  • Disconnected from the target VM, address: '127.0.0.1:56577', transport: 'socket'
    DisconnectedfromthetargetVM,address:'127.0.0.1:56577',transport:'socket'端口占用DisconnectedfromthetargetVM,address:'127.0.0.1:56577',transport:'socket'DisconnectedfromthetargetVM=与目标虚拟机断开连接。PS:......
  • 赛博朋克元素——斜拉桥智慧施工数字孪生
    斜拉桥(又称斜张桥),作为现代桥梁工程中的一种重要类型,代表了现代工程技术的高度成就,在全球范围内已得到广泛的应用。斜拉桥采用了高强度的材料和精密的建筑技术,能够跨越宽阔的河流、峡谷和深渊。在新基建计划中,斜拉桥成为城市交通的关键纽带,在城市发展、交通改善、科技创新和可持续发......
  • 3种方法,用Java找出两个List中的重复元素
    本文分享自华为云社区《如何用Java找出两个List中的重复元素,读这一篇就够了》,作者:努力的阿飞。在Java编程中,我们经常需要找出两个列表(List)中的重复元素。在本文中,我们将探讨三种方法来实现这一目标。方法一:使用HashSetJava中的HashSet是一个不允许有重复元素的集合。我们可以......
  • 刷题记录-移除元素
    刷题记录-移除元素移除元素给你一个数组nums和一个值val,你需要原地移除所有数值等于val的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用O(1)额外空间并原地修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。示例......
  • 380. O(1) 时间插入、删除和获取随机元素
    实现RandomizedSet类:RandomizedSet()初始化RandomizedSet对象boolinsert(intval)当元素val不存在时,向集合中插入该项,并返回true;否则,返回false。boolremove(intval)当元素val存在时,从集合中移除该项,并返回true;否则,返回false。intgetRandom()随机返回现......
  • C++桶排序算法的应用:存在重复元素 III
    题目给你一个整数数组nums和两个整数indexDiff和valueDiff。找出满足下述条件的下标对(i,j):i!=j,abs(i-j)<=indexDiffabs(nums[i]-nums[j])<=valueDiff如果存在,返回true;否则,返回false。示例1:输入:nums=[1,2,3,1],indexDiff=3,valueDiff=0输出......
  • 如何用Java找出两个List中的重复元素,读这一篇就够了
     在Java编程中,我们经常需要找出两个列表(List)中的重复元素。在本文中,我们将探讨三种方法来实现这一目标。 方法一:使用HashSetJava中的HashSet是一个不允许有重复元素的集合。我们可以利用这个特性,通过合并两个List并计算差集,来找出重复的元素。以下是一个通过使用HashSet数......
  • ConcurrentModificationException异常,for循环遍历时候, add或者remove减少集合的元素时
    ConcurrentModificationException异常一:ConcurrentModificationException异常:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。二:遍历list集合时删除元素出现的异常publicstaticvoidmain(String[]args){ArrayList<String>list=newArrayList<String>();......
  • laravel:多mysql数据库(10.27.0 )
    一,相关文档https://learnku.com/docs/laravel/10.x/database/14882#2cd405二,php代码1,编辑.envDB_CONNECTION=mysqlDB_HOST=127.0.0.1DB_PORT=3306DB_DATABASE=gonewsDB_USERNAME=yourusernameDB_PASSWORD=yourpasswordCO_DB_CONNECTION=mysqlCO_DB_HOST=127.0.0.1......
  • laravel:打印sql(10.27.0)
    一,php代码:1234567891011121314151617181920212223publicfunctionhome(Request$request){    //默认连接    DB::enableQueryLog();     $modelNews=newNews();    $rowsNews=$modelNews->getPage(0,1); ......