|
| 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