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][−231,231−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;
}
}