658.找到K个最接近的元素
2020-03-10
找到 K 个最接近的元素
给定一个排序好的数组,两个整数 k 和 x,从数组中找到最靠近 x(两数之
差最小)的 k 个数。返回的结果必须要是按升序排好的。如果有两个数与 x 的差值一样,优先选择数值较小的那个数。
差最小)的 k 个数。返回的结果必须要是按升序排好的。如果有两个数与 x 的差值一样,优先选择数值较小的那个数。
说明:
- k 的值为正数,且总是小于给定排序数组的长度。
- 数组不为空,且长度不超过 10^4。
- 数组里的每个元素与 x 的绝对值不超过 10^4。
示例:
输入: [1,2,3,4,5], k=4, x=3
输出: [1,2,3,4]
输入: [1,2,3,4,5], k=4, x=-1
输出: [1,2,3,4]
题解:
思路1: 二分查找 + 双指针
先用二分查找找到与X最接近的下标i, 再从i往前后截取k成为新数组
再用双指针在最前最后判断去掉差值更大的那一边直到数组长度等于K
var findClosestElements = function (arr, k, x) { const getIndex = (arr, x) => { // 二分查找找到最接近的i let l = 0; let r = arr.length - 1; let mid, i = -1; while (l < r) { mid = Math.floor((l + r) / 2); if (arr[mid] === x) { i = mid; break; } if (arr[mid] < x) l = mid + 1; if (arr[mid] > x) r = mid; } i = i > -1 ? i : l; return i; } const i = getIndex(arr, x); arr = arr.slice(Math.max(i - k, 0), Math.min(i + k, arr.length)); // 从i开始向前后截取k while (arr.length > k) { // 双指针删除差值更大的那一边 if ((x - arr[0]) <= (arr[arr.length - 1] - x)) { arr.splice(arr.length - 1, 1); } else { arr.splice(0, 1); } } return arr; }