|
| 1 | +package binary_search; |
| 2 | + |
| 3 | +import java.util.ArrayList; |
| 4 | +import java.util.Arrays; |
| 5 | +import java.util.List; |
| 6 | + |
| 7 | +public class MinimizeTheMaximumAdjacentElementDifference { |
| 8 | +record Interval(int s, int e, boolean hasMoreThanOne){ |
| 9 | +static boolean check(int a, int mid, int b, int range){ |
| 10 | +return Math.abs(mid - a) <= range && Math.abs(mid - b) <= range; |
| 11 | +} |
| 12 | +static boolean check(int a, int mid1, int mid2, int b, int range){ |
| 13 | +return Math.abs(mid1 - a) <= range && Math.abs(mid1 - mid2) <= range && Math.abs(mid2 - b) <= range; |
| 14 | +} |
| 15 | +} |
| 16 | + |
| 17 | +public static void main(String[] args) { |
| 18 | +int[] nums = new int[]{-1,10,-1,8}; |
| 19 | +int res = new MinimizeTheMaximumAdjacentElementDifference().minDifference(nums); |
| 20 | +System.out.println(res); |
| 21 | +} |
| 22 | + |
| 23 | +public int minDifference(int[] nums) { |
| 24 | +boolean noPositiveNum = Arrays.stream(nums).filter(i -> i != -1).findAny().isEmpty(); |
| 25 | +if(noPositiveNum){ |
| 26 | +return 0; |
| 27 | +} |
| 28 | +int currentMax = getCurrentMax(nums); |
| 29 | +List<Interval> intervals = buildIntervals(nums); |
| 30 | +int minStart = Integer.MAX_VALUE, maxEnd = Integer.MIN_VALUE; |
| 31 | +for (Interval interval : intervals) { |
| 32 | +minStart = Math.min(minStart, Math.min(interval.e, interval.s)); |
| 33 | +maxEnd = Math.max(maxEnd, Math.max(interval.e, interval.s)); |
| 34 | +} |
| 35 | +int l = 0, h = maxEnd, m; |
| 36 | +int ans = -1; |
| 37 | +while(l <= h){ |
| 38 | +m = l + (h - l) / 2; |
| 39 | +boolean result = checkIfThisNumberSatisfiesAllIntervals(intervals, minStart + m, maxEnd - m, m); |
| 40 | +if(result){ |
| 41 | +ans = m; |
| 42 | +h = m - 1; |
| 43 | +} else { |
| 44 | +l = m + 1; |
| 45 | +} |
| 46 | +} |
| 47 | +return Math.max(ans, currentMax); |
| 48 | +} |
| 49 | + |
| 50 | +private int getCurrentMax(int[] nums){ |
| 51 | +int currMax = Integer.MIN_VALUE; |
| 52 | +int previous = nums[0]; |
| 53 | +for(int i = 1; i < nums.length; i ++){ |
| 54 | +if(nums[i] != -1){ |
| 55 | +if(previous != -1){ |
| 56 | +currMax = Math.max(currMax, Math.abs(previous - nums[i])); |
| 57 | +} |
| 58 | +previous = nums[i]; |
| 59 | +} else { |
| 60 | +previous = -1; |
| 61 | +} |
| 62 | +} |
| 63 | +return currMax; |
| 64 | +} |
| 65 | + |
| 66 | +private List<Interval> buildIntervals(int[] nums) { |
| 67 | +int previous = -1; |
| 68 | +int minusOneCount = 0; |
| 69 | +List<Interval> intervals = new ArrayList<>(); |
| 70 | +for (int num : nums) { |
| 71 | +if (num == -1) { |
| 72 | +minusOneCount ++; |
| 73 | +} else { |
| 74 | +if (minusOneCount > 0) { |
| 75 | +intervals.add(new Interval(previous != -1 ? previous : num, num, minusOneCount > 1)); |
| 76 | +minusOneCount = 0; |
| 77 | +} |
| 78 | +previous = num; |
| 79 | +} |
| 80 | +} |
| 81 | +if(nums[nums.length - 1] == -1){ |
| 82 | +intervals.add(new Interval(previous, previous, minusOneCount > 1)); |
| 83 | +} |
| 84 | +return intervals; |
| 85 | +} |
| 86 | + |
| 87 | +boolean checkIfThisNumberSatisfiesAllIntervals(List<Interval> intervals, int minStart, int maxEnd, int maxDiff){ |
| 88 | +for (Interval interval : intervals) { |
| 89 | +if (interval.hasMoreThanOne) { |
| 90 | +boolean res1 = Interval.check(interval.s, minStart, minStart, interval.e, maxDiff); |
| 91 | +boolean res2 = Interval.check(interval.s, minStart, maxEnd, interval.e, maxDiff); |
| 92 | +boolean res3 = Interval.check(interval.s, maxEnd, minStart, interval.e, maxDiff); |
| 93 | +boolean res4 = Interval.check(interval.s, maxEnd, maxEnd, interval.e, maxDiff); |
| 94 | +if (!res1 && !res2 && !res3 && !res4) { |
| 95 | +return false; |
| 96 | +} |
| 97 | +} else { |
| 98 | +boolean res1 = Interval.check(interval.s, minStart, interval.e, maxDiff); |
| 99 | +boolean res2 = Interval.check(interval.s, maxEnd, interval.e, maxDiff); |
| 100 | +if (!res1 && !res2) { |
| 101 | +return false; |
| 102 | +} |
| 103 | +} |
| 104 | +} |
| 105 | +return true; |
| 106 | +} |
| 107 | +} |
0 commit comments