LeetCode 303.区域检索-数组不可变(accumulate()和for循环差异分析)

给定一个整数数组  nums,求出数组从索引 到 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

说明:

  1. 你可以假设数组不可变。
  2. 会多次调用 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()时使用了其他内联函数,或者编译器进行了数据资源的申请。

posted @ 2019-03-22 13:42  Hk_Mayfly  阅读(314)  评论(0编辑  收藏  举报