【发布时间】:2020-01-09 02:23:26
【问题描述】:
我正在编写 C++ 来解决 Leetcode 中的这个问题:https://leetcode.com/problems/remove-element/
给定一个数组 nums 和一个值 val,删除它的所有实例 就地取值并返回新的长度。
不要为另一个数组分配额外的空间,你必须这样做 使用 O(1) 额外内存就地修改输入数组。
元素的顺序可以改变。你离开什么都没关系 超出新长度。
示例 1:
给定 nums = [3,2,2,3], val = 3,
您的函数应返回长度 = 2,前两个元素为 nums 为 2。
您在返回的长度之外留下什么并不重要。
我有两个解决方案:
解决方案 A:
int removeElement(vector<int>& nums, int val) {
nums.erase(remove(begin(nums), end(nums), val), end(nums));
return nums.size();
}
解决方案 B:
int removeElement(vector<int>& nums, int val) {
auto it = std::remove(nums.begin(), nums.end(), val);
return it - nums.begin();
}
在我看来,解决方案 B 应该比解决方案 A 更快。然而,结果却相反:
解决方案 A 花费了 0 毫秒,而解决方案 B 花费了 4 毫秒。
我不知道为什么remove + erase 比remove 快。
【问题讨论】:
-
还要注意两个sn-ps的代码做的事情非常不同。
-
那么差异可能是因为两个函数的行为不同。
-
0ms 和 4ms 是足够小的值,任何差异都几乎没有意义。它们很容易受到机器上运行的其他进程等因素的影响。
-
编译器可能知道erase-remove idiom,可以更好地优化它。此外,对于
std::vector擦除n的最后一个元素是单个算术运算(对于原始类型)。
标签: c++ algorithm performance stl