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]
.
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 || k > A.length || k == 0) {
return new int[]{};
}
int index = 1;
int[] arr = new int[k];
int val = findTarget(A, target);
arr[0] = A[val];
int right = val + 1;
int left = val - 1;
while (k > 1 && right <= A.length - 1 && left >= 0) {
if (A[right] - target < target - A[left]) {
arr[index] = A[right];
right++;
} else {
arr[index] = A[left];
left--;
}
index++;
k--;
}
while (k > 1 && right <= A.length - 1) {
arr[index++] = A[right++];
k--;
}
while (k > 1 && left >= 0) {
arr[index++] = A[left--];
k--;
}
return arr;
}
private int findTarget(int[] A, int target) {
int start = 0;
int end = A.length - 1;
int mid = 0;
while (start + 1 < end) {
mid = (end - start) / 2 + start;
if (A[mid] == target) {
return mid;
} else if (A[mid] > target) {
end = mid;
} else {
start = mid;
}
}
return Math.abs(A[start] - target) <= Math.abs(A[end] - target) ? start : end;
}
}