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;
}
};
本文详细解析了子数组和问题的两种解决方案:暴力枚举和前缀和+哈希映射。介绍了这两种方法的时间复杂度和空间复杂度,并提供了详细的C++代码实现,帮助读者深入理解算法原理。

468

被折叠的 条评论
为什么被折叠?



