139. 最接近零的子数组和

描述

给定一个整数数组,找到一个和最接近于零的子数组。返回第一个和最右一个指数。你的代码应该返回满足要求的子数组的起始位置和结束位置

您在真实的面试中是否遇到过这个题?  是

样例

给出[-3, 1, 1, -3, 5],返回[0, 2][1, 3], [1, 1], [2, 2] 或者 [0, 4]

挑战

O(nlogn)的时间复杂度

分析:

此题是子数组和为零的变形题,由于要求的子串和不一定,故哈希表的方法不再适用,使用解法4 - 排序即可在 O(nlogn) 内解决。具体步骤如下:

  1. 首先遍历一次数组求得子串和。
  2. 对子串和排序。
  3. 逐个比较相邻两项差值的绝对值,返回差值绝对值最小的两项。

代码:

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<int>result;
       if(nums.empty())
       return result;
       const int num_size=nums.size();
       vector<pair<int,int>>sum_index(num_size+1);
       for(int i=0;i<num_size;i++)
       {
           sum_index[i+1].first=sum_index[i].first+nums[i];
           sum_index[i+1].second=i+1;
       }
       sort(sum_index.begin(),sum_index.end());
       int min_diff=INT_MAX;
       int closest_index=1;
       for(int i=1;i<num_size+1;i++)
       {
          if(abs(sum_index[i].first-sum_index[i-1].first)<min_diff)
          {
              min_diff=abs(sum_index[i].first-sum_index[i-1].first);
              closest_index=i;
          }
       }
       int start=min(sum_index[closest_index].second,sum_index[closest_index-1].second);
       int end=max(sum_index[closest_index].second,sum_index[closest_index-1].second)-1;
       result.push_back(start);
       result.push_back(end);
       return result;
    }
};

举例说明:
数组:        -5,4,2,-3

sum_index<0,0>

sum_index<-5,1>

sum_index<-1,2>

sum_index<1,3>

sum_Index<-2,4>

排序后:-5,-2,-1,0,1

min_diff:         -3,1,    1,    1

closest_index=2, 对应排序后的-1,在sum_index中-1对应下标2

colsest_index=1,对应排序后的-2,在  sum_index中-2对应下标4 

所以 start=min(2,4)=2,   end=max(2,4)-1=3。

此题只是让求解一个最接近零的子数组即可,所以题目中if语句使用的是<

如果需要求多个最接近零的子数组,那只能在得到最小值之后,在来一个for循环,if语句中用等于。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值