Subarray Sum Closest

Given an integer array, find a subarray with sum closest to zero. Return the indexes of the first number and last number.

Example

Example1

Input: 
[-3,1,1,-3,5] 
Output: 
[0,2]
Explanation: [0,2], [1,3], [1,1], [2,2], [0,4]

Challenge

O(nlogn) time

Notice

It is guaranteed that the sum of any numbers is in [-2^{31},2^{31}-1][−2​31​​,2​31​​−1].

思路:将prefixsum的array,排序,然后比较相邻的两个sum,如果求diff最小的,注意;如果prefixsum == 0,则不用找了,找了个最佳答案,否则看最相近的;

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
     */
    private class Node {
        public int index;
        public int sum;
        public Node(int index, int sum) {
            this.index = index;
            this.sum = sum;
        }
    }
    
    public int[] subarraySumClosest(int[] nums) {
        int[] res = new int[2];
        if(nums == null || nums.length == 0) {
            return res;
        }
        int n = nums.length;
        int[] sum = new int[n + 1];
        sum[0] = 0;
        List<Node> list = new ArrayList<Node>();
        for(int i = 1; i <= n; i++) {
            sum[i] = sum[i - 1] + nums[i - 1];
            if(sum[i] == 0) {
                res[0] = 0;
                res[1] = i - 1;
                return res;
            }
            list.add(new Node(i, sum[i]));
        }
        Collections.sort(list, (a, b) ->(a.sum - b.sum));
        
        int diff = Integer.MAX_VALUE;
        for(int i = 0; i < list.size() - 1; i++) {
            int curdiff = list.get(i + 1).sum - list.get(i).sum;
            if(curdiff < diff) {
                diff = curdiff;
                // sum[i, j] = S[j] - S[i - 1], 所以真正的区间是: [i + 1, j]
                if(list.get(i).index < list.get(i + 1).index) {
                    res[0] = list.get(i).index;
                    res[1] = list.get(i + 1).index - 1;
                } else {
                    res[0] = list.get(i + 1).index;
                    res[1] = list.get(i).index - 1;
                }
            }
        }
        return res;
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值