658. Find K Closest Elements

Given a sorted array, two integers k and x, find the k closest elements to x in the array. The result should also be sorted in ascending order. If there is a tie, the smaller elements are always preferred.

Example 1:

Input: [1,2,3,4,5], k=4, x=3
Output: [1,2,3,4]

Example 2:

Input: [1,2,3,4,5], k=4, x=-1
Output: [1,2,3,4]

Note:

  1. The value k is positive and will always be smaller than the length of the sorted array.
  2. Length of the given array is positive and will not exceed 104
  3. Absolute value of elements in the array and x will not exceed 104

分析:

这题有两种解法,用于解决不同情况的问题:

1. 如果array 长度和 k 非常接近, 我们可以从array的最左边或者最右边移除 array.length - k个值就可以了。

2. 如果array长度远远大于k,我们可以先找到最大的一个数并且比x小的那个数,然后再以那个数开始从左右扩展,直到取到k个数。

方法一:

 1 class Solution {
 2     public List<Integer> findClosestElements(int[] arr, int k, int x) {
 3         int left = 0, right = arr.length - 1;
 4         
 5         int remaining = arr.length - k;
 6         while(remaining >= 1) {
 7             if (Math.abs(x - arr[left]) > Math.abs(arr[right] - x)) {
 8                 left++;
 9             } else {
10                 right--;
11             }
12             remaining--;
13         }
14         List<Integer> list = new ArrayList<>();
15         for (int i = left; i <= right; i++) {
16             list.add(arr[i]);
17         }
18         return list;
19     }
20 }

方法二:

 1 class Solution {
 2     public List<Integer> findClosestElements(int[] arr, int k, int x) {
 3         int closest = closest(arr, x);
 4         int left = closest;
 5         int right = closest;
 6         while (k > 1) {
 7             if (Math.abs(x - getValue(arr, left - 1)) <= Math.abs(x - getValue(arr, right + 1))) {
 8                 left--;
 9             } else {
10                 right++;
11             }
12             k--;
13         }
14         
15         List<Integer> list = new ArrayList<>();
16         for (int i = left; i <= right; i++) {
17             list.add(arr[i]);
18         }
19         return list;
20     }
21     
22     private int closest(int[] arr, int x) {
23         int left = 0, right = arr.length - 1;
24         while (left <= right) {
25             int mid = left + (right - left) / 2;
26             if (arr[mid] == x) {
27                 return mid;
28             } else if (arr[mid] < x) {
29                 left = mid + 1;
30             } else {
31                 right = mid - 1;
32             }
33         }
34         if (right < 0) return left;
35         if (left >= arr.length) return right;
36         return Math.abs(x - arr[left]) > Math.abs(x - arr[right]) ? right : left;
37     }
38     
39     private long getValue(int[] arr, int idx) {
40         if (idx < 0) return Integer.MIN_VALUE;
41         if (idx >= arr.length) return Integer.MAX_VALUE;
42         return arr[idx];
43     }
44 }

 

posted @ 2019-02-19 06:51  北叶青藤  阅读(134)  评论(0编辑  收藏  举报