给你一个数组 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();
}
};
当你调用remove(nums.begin(), nums.end(), val),它实际上并没有真正地删除元素,而是将等于val的元素移到容器的末尾,并返回一个新的迭代器,指向新的末尾位置。这个新的迭代器减去容器的起始迭代器nums.begin()就得到了移除元素的数量,也就是被移到末尾的元素的数量。
这种设计的目的是为了保持容器的大小不变,但在容器中将特定值移到末尾,以便稍后可以使用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;
}
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
// 删除键为2的元素
myMap.erase(2);
请注意,在使用 erase 函数时,务必小心,确保提供正确的迭代器或键,以避免不必要的错误。