459.排序数组中最接近元素

描述

在一个排好序的数组 A 中找到 i 使得 A[i] 最接近 target

注意事项

There can be duplicate elements in the array, and we can return any of
the indices with same value.

样例

[1, 2, 3] target = 2, 返回 1.
[1, 4, 6] target = 3, 返回 1.
[1, 4, 6] target = 5, 返回 1 或者 2.
[1, 3, 3, 4] target = 2, 返回 0 或者 1 或者 2.

挑战

O(logn) time complexity.

代码

public class Solution {
    /**
     * @param A an integer array sorted in ascending order
     * @param target an integer
     * @return an integer
     */
    public int closestNumber(int[] A, int target) {
        if (A == null || A.length == 0) {
            return -1;
        }
        int index = firstIndex(A, target);
        if (index == 0) {
            return 0;
        }
        if (index == A.length) {
            return A.length - 1;
        }
        if (Math.abs(A[index] - target) < Math.abs(A[index - 1] - target)) {
            return index;
        }
        return index - 1;
    }
    
    //定义一个方法,典型的二分查找模板   
    private int firstIndex(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) {
                return mid;
            }
            if (A[mid] < target) {
                start = mid;
            }
            if (A[mid] > target) {
                end = mid;
            }
        }
        //检查
        /* 正常情况下target应该处于两个数之间,但是存在两种特殊情况,
         * 一个是target小于A[0],一个是target大于A[A.length - 1]
         */
        /* 此为正常情况在两数之间,先返回end,然后用closestNumber代码
         * 中的第三个if判断下到底end还是end - 1最接近(target不一定在
         * 数组中存在,即不一定是整数,但此种情况下必在end,end - 1之间(此
         * 时start等于end - 1)两个数之间,除非target超出数组最后一个值,
         * 否则不会出现target在数组中间且大于 A[end]这种情况,二分法
         * 查找end不会出现这种错误思维,逻辑上分析,如果出现,证明
         * 二分法没有查找定位到最后,还应该继续二分查找)
         */
        if (A[end] >= target) {
            return end;
        }
        //此为正常情况的A[start] = target和异常情况target < A[0]此时start = 0
        if (A[start] >= target) {
            return start;
        }
        //此为异常情况的target大于A[A.length - 1]
        return A.length;
    }
}

你可能感兴趣的:(459.排序数组中最接近元素)