Given an integer array, find a subarray with sum closest to zero. Return the indexes of the first number and last number.
变化为prefixSum里面找最接近的两个数
如何找最接近?把prefixSum按数值排序,相邻的最有可能最接近,扫一遍之后得到min。因为可以任意返回,所以只有比当前min小才更新,否则不更新。(有一个比较有病的test case,因为最初一般会把min设置成Integer,MAX_VALUE,有一个test case输入就是这个MAX_VALUE,造成min index没有更新,于是IndexOutOfBoundsException)
Key Point是prefixSum中的index代表的是前i个数的和,而不是加到当前index i的和。
在最后譬如
index 4 1 2 3 0 5
prefixSum -4 -3 -2 -1 0 1
left right
minIndex = 1
right = sumList.get(minIndex).index = 1;
left = sumList.get(minIndex - 1).index = 4;
注意它们代表的是前1个数的sum: index = 0 和前4个数的sum: index = 0, 1, 2, 3
相减之后参与的index有 1, 2, 3
也就是说较大的index最后要减1
这部分代码写的比较丑,不过也没有办法。看了九章的答案,也没好到哪里去。
class Tuple {
public int index;
public int prefixSum;
public Tuple(int index, int prefixSum) {
this.index = index;
this.prefixSum = prefixSum;
}
}
class TupleComparator implements Comparator<Tuple> {
@Override
public int compare(Tuple t1, Tuple t2) {
return t1.prefixSum - t2.prefixSum;
}
}
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
*/
public int[] subarraySumClosest(int[] nums) {
// write your code here
if (nums == null || nums.length == 0) return new int[]{-1, -1};
List<Tuple> sumList = new ArrayList<>();
int sum = 0;
sumList.add(new Tuple(0, sum));
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
sumList.add(new Tuple(i + 1, sum));
}
Collections.sort(sumList, new TupleComparator());
long minDifference = Long.MAX_VALUE;
int minIndex = -1;
for (int i = 1; i < sumList.size(); i++) {
int difference = Math.abs(sumList.get(i).prefixSum - sumList.get(i - 1).prefixSum);
if (difference < minDifference) {
minDifference = difference;
minIndex = i;
}
}
// left is i - 1, right is i
//left index sumList.get(i - 1).index
//right index sumList.get(i).index
int left = sumList.get(minIndex - 1).index;
int right = sumList.get(minIndex).index;
return new int[] {Math.min(left, right), Math.max(left, right) - 1};
}
}
No comments:
Post a Comment