Leetcode刷题总结:303. Range Sum Query - Immutable

Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive.

Example:

Given nums = [-2, 0, 3, -5, 2, -1]

sumRange(0, 2) -> 1
sumRange(2, 5) -> -1
sumRange(0, 5) -> -3

Note:

  1. You may assume that the array does not change.
  2. There are many calls to sumRange function.

解题:

思路一:

因为看到题目的要求是sumRange要频繁的调用,所以第一个想到的是用空间换时间,用一个二维数组,行i表示start,列j表示end, _sumRange[i][j]就表示计算从i到j的和,这样调用sumRange的是可以直接取到对应的结果,代码如下:

class NumArray {
    private:
    //vector<int> _nums;
    int *_sumRanges;
    int size;
public:
    NumArray(vector<int> nums) {
        //_nums = nums;
        size = nums.size();
        _sumRanges = (int *)malloc(size*size*sizeof(int));
        for (int i = 0; i < size; ++i) {
            int sum = 0;
            for (int j = i; j < size; ++j) {
                sum += nums[j];
                _sumRanges[i*size + j] = sum;
            }            
        }
    }
    
    int sumRange(int i, int j) {
        return _sumRanges[i*size + j];
    }
};

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray obj = new NumArray(nums);
 * int param_1 = obj.sumRange(i,j);
 */

结果提交的时候发现内存使用超过限制了;

 

思路二:保存原始的数组,每次都计算一下

class NumArray {
    private:
    vector<int> _nums;
    //int *_sumRanges;
    //int size;
public:
    NumArray(vector<int> nums) {
        _nums = nums;
    }
    
    int sumRange(int i, int j) {
        int sumResult = 0;
        for (int x = i; x <= j; ++x) {
            sumResult += _nums[x];
        }
        return sumResult;
    }
};

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray obj = new NumArray(nums);
 * int param_1 = obj.sumRange(i,j);
 */

好吧这次提交通过了,但是性能超级差,在最后4%, 耗时1612ms;

思路三:怎么优化能减少时间和空间呢?

我用一个数组存从[0, i]的总和,则计算从i到j的总和的时候,只需要知道sum[i]和sum[j], 用sum[j]-sum[i] 就是(i,j], 那么计算[i,j]的和就是再加上num[i];

class NumArray {
private:
    vector<int> _nums;
    vector<int> _sums;

public:
    NumArray(vector<int> nums) {
        _nums = nums;
        _sums.resize(nums.size());
        if (_nums.size() <= 0) {
            return;
        }
        _sums[0] = nums[0];
        for (int i = 1; i < nums.size(); ++i) {
            _sums[i] = nums[i] + _sums[i-1];
        }
    }
    
    int sumRange(int i, int j) {   
        if (_nums.size() <= 0 || i > j || j >= _nums.size()) {
            return 0;
        }
        return _sums[j]-_sums[i]+_nums[i];
    }
};

运行时间236ms

posted @ 2017-08-27 17:35  糯米团子syj  阅读(119)  评论(0编辑  收藏  举报