给定一个整数数组,找到一个和最接近于零的子数组。返回第一个和最有一个指数。你的代码应该返回满足要求的子数组的起始位置和结束位置
样例
给出[-3, 1, 1, -3, 5],返回[0, 2],[1, 3], [1, 1], [2, 2] 或者[0, 4]
挑战
O(nlogn)的时间复杂度
分析:首先O(n^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> subarraySumClosest(vector<int> nums){
// write your code here
vector<pair<int,int> > sum;
int temp = 0;
sum.push_back(make_pair(temp,-1));
for(int i=0;i<nums.size();i++)
{
temp+=nums[i];
sum.push_back(make_pair(temp,i));
}
sort(sum.begin(),sum.end());
int start,end;
int diff = INT_MAX;
for(int i=1;i<sum.size();i++)
{
if(abs(sum[i].first-sum[i-1].first)<=diff)
{
diff = abs(sum[i].first-sum[i-1].first);
start = min(sum[i].second,sum[i-1].second)+1;
end = max(sum[i].second,sum[i-1].second);
}
}
vector<int> ret;
ret.push_back(start);
ret.push_back(end);
return ret;
}
};