Given an integer array, find a subarray with sum closest to zero. Return the indexes of the first number and last number.
Example
Given [-3, 1, 1, -3, 5], return [0, 2], [1, 3], [1, 1], [2, 2] or [0, 4]
The problem is quite different from Subarray Sum, which uses hash table to solve the problem.
Instead, we use the follow algorithm:
Time: O(nlgn)
Space: O(n)
public class Solution {
public ArrayList<Integer> subarraySumClosest(int[] nums) {
ArrayList<Integer> result = new ArrayList<>();
Pair[] sumIndexArr = new Pair[nums.length + 1];
sumIndexArr[0] = new Pair(0, -1);
for (int i = 0; i < nums.length; i++) {
sumIndexArr[i + 1] = new Pair(sumIndexArr[i].sum + nums[i], i);
}
Arrays.sort(sumIndexArr);
int minDiff = Integer.MAX_VALUE;
int minIndex = 0;
for (int i = 1; i <= nums.length; i++) {
int diff = sumIndexArr[i].sum - sumIndexArr[i - 1].sum;
if (diff < minDiff) {
minDiff = diff;
minIndex = i - 1;
}
}
if (sumIndexArr[minIndex].index < sumIndexArr[minIndex + 1].index) {
result.add(sumIndexArr[minIndex].index + 1);
result.add(sumIndexArr[minIndex + 1].index);
} else {
result.add(sumIndexArr[minIndex + 1].index + 1);
result.add(sumIndexArr[minIndex].index);
}
return result;
}
class Pair implements Comparable<Pair> {
int sum;
int index;
public Pair(int sum, int index) {
this.sum = sum;
this.index = index;
}
@Override
public int compareTo(Pair that) {
return this.sum - that.sum;
}
}
}