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].Challenge
O(nlogn) time
Solution:The naive solution is for each presum[j], check out all its previous presum[i -1] and calculate the closest one. The overall time complexity is O(n^2).
A better solution is to use a TreeMap, where elements are sorted in the tree. Then for each presum[j], we only need to find out the closest element in the tree, which takes time of O(logn). So the overall time complexity is O(nlogn).
Code (java):
public class Solution {
/**
* @param A: an integer array
* @param target: An integer
* @param k: An integer
* @return: an integer array
*/
public int[] kClosestNumbers(int[] A, int target, int k) {
// write your code here
if (A == null || A.length == 0) {
return new int[0];
}
int[] ans = new int[k];
// step 1: find the position of the largest number smaller than the target
//
int start = findCloestNumber(A, target);
int end = start + 1;
// step 2: find the k-cloest numbers
//
for (int i = 0; i < k; i++) {
if (start < 0) {
ans[i] = A[end];
end++;
} else if (end >= A.length) {
ans[i] = A[start];
start--;
} else if (Math.abs(A[start] - target) <= Math.abs(A[end] - target)) {
ans[i] = A[start];
start--;
} else {
ans[i] = A[end];
end++;
}
}
return ans;
}
// find the first position of the closet number which is smaller than the target
//
private int findCloestNumber(int[] A, int target) {
int start = 0;
int end = A.length - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (A[mid] == target) {
end = mid;
} else if (A[mid] > target) {
end = mid;
} else {
start = mid;
}
}
if (A[end] < target) {
return end;
}
if (A[start] < target) {
return start;
}
return -1;
}
}
No comments:
Post a Comment