K Closest Numbers In Sorted Array
Given a target number, a non-negative integer k and an integer array A sorted in ascending order, find the k closest numbers to target in A, sorted in ascending order by the difference between the number and target. Otherwise, sorted in ascending order by number if the difference is same.
Example
Given A = [1, 2, 3], target = 2 and k = 3, return [2, 1, 3].
Given A = [1, 4, 6, 8], target = 3 and k = 3, return [4, 1, 6].
Solution: First search target, then try both sides of target. Attention that if we can not find the target, the start and end pointer can not be decide which side to go. So we need obtain the minimun one as sorted in ascending order by number if the difference is same.
public int[] kClosestNumbers(int[] A, int target, int k) {
if(A == null || A.length == 0) {
return new int[0];
}
int[] res = new int[k];
int index = binarySearch(A, target);
int n1 = index, n2 = index + 1;
for(int i = 0; i < k; i++) {
if(n1 < 0) {
res[i] = A[n2];
n2++;
}
else if(n2 >= A.length) {
res[i] = A[n1];
n1--;
}
else if(Math.abs(target - A[n1]) <= Math.abs(target - A[n2])) {
res[i] = A[n1];
n1--;
}
else {
res[i] = A[n2];
n2++;
}
}
return res;
}
public int binarySearch(int[] A, int target) {
int start = 0, end = A.length - 1;
while(start <= end) {
int mid = start + (end - start) / 2;
if(A[mid] == target) {
return mid;
}
else if(A[mid] < target) {
start = mid + 1;
}
else {
end = mid - 1;
}
}
return Math.min(start, end);
}