diff --git a/src/main/java/com/cool/ling_cha_mount/binary_search/Num658.java b/src/main/java/com/cool/ling_cha_mount/binary_search/Num658.java new file mode 100644 index 0000000..edb810c --- /dev/null +++ b/src/main/java/com/cool/ling_cha_mount/binary_search/Num658.java @@ -0,0 +1,87 @@ +package com.cool.ling_cha_mount.binary_search; + +import org.junit.Test; + +import java.util.*; + +public class Num658 { + + + public List findClosestElements1(int[] arr, int k, int x) { + int size = arr.length; + int left = 0; + int right = size - k; + while (left < right) { + // int mid = left + (right - left) / 2; + int mid = (left + right) / 2; + // 尝试从长度为 k + 1 的连续子区间删除一个元素 + // 从而定位左区间端点的边界值 + if (x - arr[mid] > arr[mid + k] - x) { + // 下一轮搜索区间是 [mid + 1..right] + left = mid + 1; + } else { + // 下一轮搜索区间是 [left..mid] + right = mid; + } + } + + List res = new ArrayList<>(); + for (int i = left; i < left + k; i++) { + res.add(arr[i]); + } + return res; + } + + public List findClosestElements(int[] arr, int k, int x) { + int i = binarySearch(arr, x); + if (i < 0) { + List list = new ArrayList<>(); + for (int j = 0; j < k; j++) { + list.add(arr[j]); + } + return list; + } + int left = i; + int right = i+1; + List list = new ArrayList<>(); + while (k > 0) { + if (right < arr.length && left >= 0) { + if (x - arr[left] >= arr[right] - x) { + list.add(arr[right]); + right++; + } else { + list.add(arr[left]); + left--; + } + } else if (right < arr.length) { + list.add(arr[right]); + right++; + } else { + list.add(arr[left]); + left--; + } + k--; + } + list.sort(Comparator.comparing((a) -> a)); + return list; + } + + private int binarySearch(int[] nums, int target) { + int left = -1; + int right = nums.length; + while (left + 1 < right) { + int mid = (left + right) >>> 1; + if (target < nums[mid]) { + right = mid; + } else { + left = mid; + } + } + return left; + } + + @Test + public void test() { + findClosestElements(new int[]{1,1,1,10,10,10}, 1, 9); + } +}