http://www.lintcode.com/zh-cn/problem/subarray-sum/#
思路1:Brute Force
最容易想到的方法就是暴力枚举子数组,计算和,并返回和为0的子数组。
Time complexity: O(n^2)
Space complexity: O(1)
class Solution {
public:
/**
* @param nums: A list of integers
* @return: A list of integers includes the index of the first number
* and the index of the last number
*/
vector<int> subarraySum(vector<int> nums){
vector<int> ret;
int n = nums.size();
for (int i = 0; i < n; ++i) {
int sum = 0;
for (int j = i; j < n; ++j) {
sum += nums[j];
if (sum == 0) {
ret.push_back(i);
ret.push_back(j);
return ret;
}
}
}
return ret;
}
};
思路2:Prefix Sum + Hash Map
扫描一次数组,跟踪前缀和并用一个Hash Map保存(前缀和, 结尾位置)的key-value pair。每到一个位置i,计算前缀和sum,并判断:
- sum是否为0,如果是,记录区间并返回
- 在Hash Map中是否有key为sum的key-value pair,如果有,设这样的key-value pair为(sum, j),和为0的子数组为nums[j+1...i]记录区间并返回
Time complexity: O(n)
Space complexity: O(n)
class Solution {
public:
/**
* @param nums: A list of integers
* @return: A list of integers includes the index of the first number
* and the index of the last number
*/
vector<int> subarraySum(vector<int> nums){
vector<int> ret;
unordered_map<long long, int> mymap;
unordered_map<long long, int>::iterator it;
long long sum = 0;
for (int i = 0; i < nums.size(); ++i) {
sum += nums[i];
if (sum == 0) {
ret.push_back(0);
ret.push_back(i);
return ret;
}
it = mymap.find(sum);
if (it != mymap.end()) {
ret.push_back(it->second + 1);
ret.push_back(i);
return ret;
} else {
mymap[sum] = i;
}
}
return ret;
}
};
上面的代码可以简化,在循环之前加上maymap[0] = -1
就可以将判断1和2统一起来:
class Solution {
public:
/**
* @param nums: A list of integers
* @return: A list of integers includes the index of the first number
* and the index of the last number
*/
vector<int> subarraySum(vector<int> nums){
vector<int> ret;
unordered_map<long long, int> mymap;
unordered_map<long long, int>::iterator it;
mymap[0] = -1; // 加上这句可以简化代码
long long sum = 0;
for (int i = 0; i < nums.size(); ++i) {
sum += nums[i];
it = mymap.find(sum);
if (it != mymap.end()) {
ret.push_back(it->second + 1);
ret.push_back(i);
return ret;
}
mymap[sum] = i;
}
return ret;
}
};