在这里提供一个第二题解法,但是直觉告诉我可能不是最优的,因为搜索范围是[-10^9, 10^9],数组长度最大在10^5,感觉这个数量级走两遍binary search还是很容易TLE。抛砖引玉,看看有没有更好的解法
- public class Main {
- public static void main(String[] args) {
- List<Integer> center = new ArrayList<>();
- center.add(-2);
- center.add(1);
- center.add(0);
- long d = 8;
-
- System.out.println(numberOfSuitableLocations(center, d));
- }
-
- public static int numberOfSuitableLocations(List<Integer> center, long d) {
- int n = center.size();
- d /= 2;
-
- Collections.sort(center);
-
- long minDistance = 0L;
- for(int i = 0; i < n / 2; i++) {
- minDistance += center.get(n - 1 - i) - center.get(i);
- }
- if(minDistance > d)
- return 0;
-
- int left = searchLeft(center, -1_000_000_000, center.get(n / 2), d);
- int right = searchRight(center, center.get(n / 2), 1_000_000_000, d);
-
- return right - left + 1;
- }
-
- private static int searchLeft(List<Integer> center, int start, int end, long d) {
- while(start < end) {
- int mid = start + (end - start) / 2;
- if(canFulfill(center, mid, d)) {
- end = mid;
- } else {
- start = mid + 1;
- }
- }
- return start;
- }
-
- private static int searchRight(List<Integer> center, int start, int end, long d) {
- while(start < end) {
- int mid = start + (end - start + 1) / 2;
- if(canFulfill(center, mid, d)) {
- start = mid;
- } else {
- end = mid - 1;
- }
- }
- return start;
- }
-
- private static boolean canFulfill(List<Integer> center, int mid, long d) {
- long distance = 0L;
- for(int c: center) {
- distance += (long)Math.abs(mid - c);
- if(distance > d)
- return false;
- }
- return true;
- }
- }
复制代码 |