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:
- The value k is positive and will always be smaller than the length of the sorted array.
- Length of the given array is positive and will not exceed 104
- 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 - 1) { 25 int mid = left + (right - left) / 2; 26 if (arr[mid] == x) { 27 return mid; 28 } else if (arr[mid] < x) { 29 left = mid; 30 } else { 31 right = mid; 32 } 33 } 34 // narrow down to the case we only have 2 elements in the array. 35 return Math.abs(x - arr[left]) <= Math.abs(x - arr[right]) ? left: right; 36 } 37 38 private long getValue(int[] arr, int idx) { 39 if (idx < 0) return Integer.MIN_VALUE; 40 if (idx >= arr.length) return Integer.MAX_VALUE; 41 return arr[idx]; 42 } 43 }

浙公网安备 33010602011771号