139.Subarray Sum Closest-最接近零的子数组和(中等题)

来源:互联网 发布:免费阅读软件下载 编辑:程序博客网 时间:2024/05/16 12:26

最接近零的子数组和

  1. 题目

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

  2. 样例

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

  3. 挑战

    O(nlogn)的时间复杂度

  4. 题解

    本题求数组中区间[i,j],使得该区间内所有元素之和最接近于0。则Sum[i,j]=Sum[0,j]-Sum[0,i-1]。为了优化时间复杂度,我们构建一个数据结构Sum保存Sum[0,j]和j的值。
    对数组进行遍历,将Sum[0,j]及j依次存入一个Sum数组,再对其按sum属性大小进行排序,此时只需找到一对Sum[a],Sum[b]使得Sum[a]-Sum[b]最小,则从a,b的index属性即可得到答案。
    如nums[-3, 1, 1, -3, 5],
    遍历后得到Sum数组[0(0),-3(1),-2(2),-1(3),-4(4),1(5)],括号中表示index属性。
    排序后得到[-4(4),-3(1),-2(2),-1(3),0(0),1(5)],
    遍历可知Sum[a]-Sum[b]最小值为1,取a=1(5),b=-4(4),再从index值分析可得到答案。

public class Solution {    /**     * @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     */    class Sum    {        public int sum;        public int index;        public Sum(int sum, int index)        {            this.sum = sum;            this.index = index;        }    }    public int[] subarraySumClosest(int[] nums) {        int[] res = new int[2];        if (nums == null || nums.length == 0)         {            return res;        }         int len = nums.length;        if(len == 1)         {            res[0] = res[1] = 0;            return res;        }        Sum[] sums = new Sum[len+1];        sums[0] = new Sum(0,0);        int pre = 0;        for (int i=1;i<=len;i++)        {            sums[i] = new Sum(pre + nums[i-1],i);            pre = sums[i].sum;        }        Arrays.sort(sums, new Comparator<Sum>()         {           public int compare(Sum a, Sum b)            {               return a.sum - b.sum;           }         });        int min = Integer.MAX_VALUE;        for (int i=1;i<=len;i++)        {            if (min > sums[i].sum - sums[i-1].sum)            {                min = sums[i].sum - sums[i-1].sum;                res[0] = Math.min(sums[i].index, sums[i - 1].index);                res[1] = Math.max(sums[i].index, sums[i - 1].index) - 1;            }        }        return res;    }}

Last Update 2016.10.17

0 0