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: 

     /* findFirst() is to find the first index of number that is larger or equal to target, the way is binary search

  * "target - A[start] >= A[end] - target" is keep order ascending when left and right have same diff

   */

  public int[] kClosestNumbers(int[] A, int target, int k) {

    int[] ret = new int[k];

    if (A == null || A.length < k) {

      return ret;

    }

    int start = findFirst(A, target) - 1;

    int end = start + 1;

    for (int i = 0; i < k; i++) {

      if (start < 0) {

        ret[i] = A[end++];

      } else if (end >= A.length) {

        ret[i] = A[start--];

      } else {

        if (target - A[start] >= A[end] - target) {

          ret[i] = A[start--];

        } else {

          ret[i] = A[end++];

        }

      }

    }

    return ret;

  }

 

private int findFirst(int[] A, int target) {

  if (A == null || A.length == 0) {

    return -1;    

  }

  int start = 0;

  int end = A.length - 1;

  int mid = 0;

  while (start + 1 < end) {

    mid = start + (end - start) / 2;

    if (A[mid] < target) {

      start = mid;

    } else {

      end = mid;

    }

  }

  if (A[start] >= target) {

    return start;

  } else if (A[end] >= target) {

    return end;

  } else {

    return A.length;

  }

}

 

posted @ 2017-07-15 08:16  setNULL  阅读(83)  评论(0编辑  收藏  举报