LeetCode 303.区域检索-数组不可变(accumulate()和for循环差异分析)
给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点。
示例:
给定 nums = [-2, 0, 3, -5, 2, -1],求和函数为 sumRange() sumRange(0, 2) -> 1 sumRange(2, 5) -> -1 sumRange(0, 5) -> -3
说明:
- 你可以假设数组不可变。
- 会多次调用 sumRange 方法。
#include <vector> #include <iostream> #include <numeric> using namespace std; static int x = []() {std::ios::sync_with_stdio(false); cin.tie(0); return 0; }(); class NumArray { public: NumArray(vector<int> nums) { sumnums = nums; } int sumRange(int i, int j) { return accumulate(sumnums.begin()+i, sumnums.begin()+j+1, 0); } private: vector<int> sumnums; }; int main() { vector<int> vec = {-2, 0, 3, -5, 2, -1}; NumArray *A = new NumArray(vec); cout << A->sumRange(0, 2); return 0; }
#include <vector> #include <iostream> #include <numeric> using namespace std; static int x = []() {std::ios::sync_with_stdio(false); cin.tie(0); return 0; }(); class NumArray { public: NumArray(vector<int> nums) { for(int i = 1; i < nums.size(); ++i){ nums[i] += nums[i-1]; } sumnums = nums; } int sumRange(int i, int j) { if(i == 0) return sumnums[j]; return sumnums[j] - sumnums[i-1]; } private: vector<int> sumnums; }; int main() { vector<int> vec = {-2, 0, 3, -5, 2, -1}; NumArray *A = new NumArray(vec); cout << A->sumRange(0, 2); return 0; }
上面是accumulate()下面是for循环
template <class InputIterator, class T> T accumulate (InputIterator first, InputIterator last, T init) { while (first!=last) { init = init + *first; // or: init=binary_op(init,*first) for the binary_op version ++first; } return init; }
时间复杂度同是O(n),耗时差这么多。
举个栗子
#include <iostream> #include <vector> #include <numeric> using namespace std; vector<int> vec = { 1, 2, -5, 6 }; int sum; void func1() { for (int i = 0; i < vec.size(); ++i) { sum += vec[i]; } } void func2() { accumulate(vec.begin(), vec.end(), 0); } int main() { return 0; }
直接查看汇编代码
首先我怀疑编译器在进行begin()操作或者使用容器时,耗费了时间。
void func1() { for (int i = 0; i < vec.size(); ++i) { sum += *(vec.begin()+i); } }
同时将LeetCode上for循环数组形式改为begin()形式。
得到汇编代码和运行结果
并没有影响,那么唯一的可能性是,在调用accumulate()时使用了其他内联函数,或者编译器进行了数据资源的申请。