lintcode 138
子数组之和为零
给定一个整数数组,找到和为零的子数组。你的代码应该返回满足要求的子数组的起始位置和结束位置
这里给定是思路是这样的,依次求数组nums的前缀和,其前缀和的数组为S,
对于S[i],S[j],(i>j)如果S[i],S[j],相等,这说明nums[i+1],nums[i+2]....nums[j]的子数组的和为0;
这里利用hash表来检查两个前缀数组,将将前缀数组的值存入hash表中,每次存入是检查是否有重复的碰撞,存在重复表明后缀数组中两个数相等.
另外还有一种情况,那就是对于类似1,-1,2这样的后缀数组,从nums[0],nums[1]....nums[i],这样的后缀数组是无法检测的.因此我们在哈希表中加入一个特殊值,s[-1] = 0,表示从0位开始的和为0.这样就可以检查从0开始的子数组了.
代码如下
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){
// write your code here
hash_map<int, int> Sum;
int NowSum = 0;
int Count = 0;//计数值
vector<int> Result;
Sum.insert(pair<int, int>(0, -1));//插入
for(; Count != nums.size(); Count++)
{
NowSum += nums[Count];
if(Sum.find(NowSum) == Sum.end())//检查是否存在NowSum相等的键
Sum.insert(pair<int, int>(NowSum, Count));//插入
else//存在前缀相等
{
hash_map<int,int>::iterator ite = Sum.find(NowSum);
Result.push_back(ite->second +1);
Result.push_back(Count);
return Result;
}
}
return Result;
}
};