Find Closest Number in a Sorted Array

Question (LI.459)

Given a target integer and a sorted integer array, return the index that has the closest value to the target.

Does the array have both positive and negative number? Yes. Does the array contain duplicates? Yes. What if two numbers have the same difference? return any index

Example

([1,2,3], 2) => 1
([1,3,3,4], 2) => return either 0,1,2 will be fine
([1,4,6], 5) => return either 1 or 2

Scan the array keep a difference value. Terminate the search once the defference is increasing.

public int closestNumber(int[] A, int target) {
    // edge check
    if (A == null || A.length == 0) {
        return -1;
    }
    // linear search
    int minDiff = diff(A[0], target);
    int i = 1;
    for (i = 1; i < A.length; i++) {
        int curDiff = diff(A[i], target);
        if (curDiff >= minDiff) {
            return i - 1;
        } else {
            minDiff = curDiff;
        }
    }
    // return last index
    return i-1;
}

private int diff(int num1, int num2) {
    return Math.abs(num1 - num2);
}

Linear time O(n)

The array is sorted. We can use an O(1) check to prune half of the search place. This is the only way to beat a linear solution.

O(1) check 3 cases

  • A[mid] > target: prune right section, search left section

  • A[mid] == target: return mid

  • A[mid] < target: prune left section, search right section

public int closestNumber(int[] A, int target) {
    // edge check
    if (A == null || A.length == 0) {
        return -1;
    }
    // binary search
    int left = 0, right = A.length - 1;
    int mid;
    while (left + 1 < right) {
        mid = (left + right) / 2;

        if (A[mid] > target) {
            right = mid;
        } else if (A[mid] == target) {
            return mid;
        } else {
            left = mid;
        }
    }
    // check adjacent
    if (diff(A[left], target) < diff(A[right], target)) {
        return left;
    } else {
        return right;
    }
}

Simple recrusion can be implemented with while loop. Logarithmic time with constant space.

Last updated