leetcode-pp / 91alg-6-daily-check

91 算法第六期打卡仓库
28 stars 0 forks source link

【Day 40 】2022-01-20 - 796. Minimum Light Radius #50

Open azl397985856 opened 2 years ago

azl397985856 commented 2 years ago

796. Minimum Light Radius

入选理由

暂无

题目地址

https://binarysearch.com/problems/Minimum-Light-Radius

前置知识

Constraints

n ≤ 100,000 where n is the length of nums Example 1 Input nums = [3, 4, 5, 6] Output 0.5 Explanation If we place the lamps on 3.5, 4.5 and 5.5 then with r = 0.5 we can light up all 4 houses.

alongchong commented 2 years ago
class Solution {
    public double solve(int[] nums) {
        Arrays.sort(nums);
        int streetLength = nums[nums.length - 1] - nums[0];
        int low = 0, high = streetLength / 3 + 1;
        while (low + 1 < high) {
            int mid = low + (high - low) / 2;
            if (isPossible(nums, mid, 3)) {
                high = mid;
            } else {
                low = mid;
            }
        }
        if (isPossible(nums, low, 3)) {
            return low / 2D;
        }
        return high / 2D;
    }

    private boolean isPossible(int[] nums, int radius, int lightNumber) {
        int lightRadius = -1;
        int currentLightNum = 0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] > lightRadius) {
                currentLightNum++;
                lightRadius = nums[i] + radius;
            }
            if (currentLightNum > lightNumber) {
                return false;
            }
        }
        return true;
    }
}
Aobasyp commented 2 years ago

思路 由于我们想要找到满足条件的最小值,因此可直接套用最左二分模板

class Solution { public double solve(int[] nums) { Arrays.sort(nums); int streetLength = nums[nums.length - 1] - nums[0]; int low = 0, high = streetLength / 3 + 1; while (low + 1 < high) { int mid = low + (high - low) / 2; if (isPossible(nums, mid, 3)) { high = mid; } else { low = mid; } } if (isPossible(nums, low, 3)) { return low / 2D; } return high / 2D; }

private boolean isPossible(int[] nums, int radius, int lightNumber) {
    int lightRadius = -1;
    int currentLightNum = 0;
    for (int i = 0; i < nums.length; i++) {
        if (nums[i] > lightRadius) {
            currentLightNum++;
            lightRadius = nums[i] + radius;
        }
        if (currentLightNum > lightNumber) {
            return false;
        }
    }
    return true;
}

}

GaoMinghao commented 2 years ago

思路

二分

代码

public class MinimumLightRadius {
    public double solve(int[] nums) {
        Arrays.sort(nums);
        int min = 0, max = (nums[nums.length-1]-nums[0])/3 + 1;
        while(min +1 < max) {
            int mid = min + (max-min)/2;
            if(isPossible(nums, mid, 3))
                max = mid;
            else
                min = mid;
        }
        if(isPossible(nums, min,3))
            return min/2.0;
        return max/2.0;
    }

    private boolean isPossible(int[] nums, int radius, int lightNumber) {
        int lightRadius = -1;
        int currentLightNum = 0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] > lightRadius) {
                currentLightNum++;
                lightRadius = nums[i] + radius;
            }
            if (currentLightNum > lightNumber) {
                return false;
            }
        }
        return true;
    }
}
577961141 commented 2 years ago

题目思路

借鉴官方解法

题目的题解code

import java.util.*;

class Solution {
    public int solve(int[] nums) {
        List<Integer> list = new ArrayList();
        int ret = 0;
        for (int i = 0; i < nums.length; i++) {
            int where = find(list, nums[i] * 3);
            ret += list.size() - where;
            list.add(find(list, nums[i]), nums[i]);
        }
        return ret;
    }
    public int find(List<Integer> list, int find) {
        int l = 0;
        int r = list.size();
        while (l < r) {
            int mid = l + (r - l) / 2;
            if (list.get(mid) > find) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        return l;
    }
}class Solution {
    solve(nums: Array<number>): number {
        if (!nums.length) return 0;
        const n = nums.length;
        nums.sort((a, b) => a - b);
        let left = 0, right = nums[n - 1] - nums[0];
        while (left <= right) {
            let mid = (left + right) >> 1;
            if (isCover(nums, mid)) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return left / 2;
    }
}

function isCover(nums: Array<number>, radius: number): boolean {
    let left = nums[0], right = left + radius;
    for (let i = 0; i < 3; i++) {
        let j = searchRight(nums, right);
        if (j >= nums.length) return true;
        left = nums[j], right = left + radius;
    }
    return false;
}

function searchRight(nums: number[], target: number, left: number = 0, right: number = nums.length): number {
    if (left < 0) throw ('left must be non-negative');
    while (left < right) {
        let mid = (left + right) >> 1;
        if (target < nums[mid]) {
            right = mid;
        } else {
            left = mid + 1;
        }
    }
    return left;
}
export { Solution }

时间和空间复杂度

ChenJingjing85 commented 2 years ago
class Solution:
    def solve(self, nums):
        light_num = 3
        nums.sort()
        n = len(nums)
        def possible(diameter):
            begin = nums[0]
            end = begin + diameter
            for i in range(3):
                idx = bisect_right(nums, end)
                if idx >= n:
                    return True
                end = nums[idx] + diameter
            return False
        l = 0
        r = nums[-1]-nums[0]#如果只有一盏灯所需最大直径
        while l <= r:
            mid = (l + r) //2
            if possible(mid):#进一步缩短
                r = mid - 1
            else:
                l = mid + 1
        return l / 2
z1ggy-o commented 2 years ago

思路

今天又抄作业了。算是击到了自己的一个痛点。

一般使用二分搜索,总是想着找一个已有的值。例如,在本题中,就是想着找 x。 但实际上应该把思路拓宽。题解里就是使用二分搜索来逼近直径。与其叫“搜索”不如叫“求值”。

简单分析之后可以发现,直径的范围一定是小于两端的房子的(取值空间)。 又,能够照亮一个房子的极值是房子正好在灯光的尽头(判定条件)。 有了这两个点,我们要做的就是代入直径,去看灯光能否将所有的房子覆盖。

代码中,取 mid 的时候使用 int 就可以的理由是所有房子的坐标都是 int。 如果房子数小于等于 3,则把灯分配给每个房子即可(半径为 0,灯插家门口得了); 当房子数大于 3 的时候,再极端的情况,灯的半径都不会小于 0.5,且会以 0.5 的倍数而变化。 继而,即使 mid 为 int,当我们逼近到最后的只有两个候选值的时候,只有其中一个能将所有房子覆盖,即那个更大的值。

代码

CPP

class Solution {
public:
    double solve(vector<int> &nums) {
        if (nums.size() <= 3) return 0;  // every house can have its own light

        sort(nums.begin(), nums.end());
        int l = 0;
        int r = nums[nums.size()-1] - nums[0];

        while (l <= r) {
            int mid = l + (r - l) / 2;
            if (all_covered(nums, mid)) {
                r = mid - 1;
            } else {
                l = mid + 1;
            }
        }
        return (double) l / 2;
    }
private:
    bool all_covered(vector<int> &nums, int r)
    {
        int begin = nums[0];
        int range = begin + r;

        int n = 0;
        for (int i = 0; i < 3; i++) {
            if (nums[n] <= range) n++;
            if (n >= nums.size()) return true;
            begin = nums[n];
            range = begin + r;
        }
        return false;
    }
}

复杂度分析

demo410 commented 2 years ago
Hacker90 commented 2 years ago

抄写答案

class Solution: def solve(self, nums): nums.sort() N = len(nums) if N <= 3: return 0 LIGHTS = 3

这里使用的是直径,因此最终返回需要除以 2

    def possible(diameter):
        start = nums[0]
        end = start + diameter
        for i in range(LIGHTS):
            idx = bisect_right(nums, end)
            if idx >= N:
                return True
            start = nums[idx]
            end = start + diameter
        return False

    l, r = 0, nums[-1] - nums[0]
    while l <= r:
        mid = (l + r) // 2
        if possible(mid):
            r = mid - 1
        else:
            l = mid + 1
    return l / 2
wxj783428795 commented 2 years ago

抄作业。。。

class Solution:
    def solve(self, nums):
        nums.sort()
        N = len(nums)
        if N <= 3:
            return 0
        LIGHTS = 3
        # 这里使用的是直径,因此最终返回需要除以 2
        def possible(diameter):
            start = nums[0]
            end = start + diameter
            for i in range(LIGHTS):
                idx = bisect_right(nums, end)
                if idx >= N:
                    return True
                start = nums[idx]
                end = start + diameter
            return False

        l, r = 0, nums[-1] - nums[0]
        while l <= r:
            mid = (l + r) // 2
            if possible(mid):
                r = mid - 1
            else:
                l = mid + 1
        return l / 2
Today-fine commented 2 years ago

看官方题解稍微理解了个大概。。。


bool isPossible(vector<int>& nums, int mid) {
    int start = nums[0];
    int end = start + mid;
    for (int i = 0; i < 3; i++) {
        int index = 0;
        while (nums[index] <= end) index++;
        if (index >= nums.size()) return true;
        start = nums[index];
        end = start + mid;
    }
    return false;
}

double solve(vector<int>& nums) {
    if (nums.size() <= 3) return 0;
    sort(nums.begin(), nums.end());
    int l = 0;
    int r = nums[nums.size() - 1] - nums[0];
    while (l <= r) {
        int mid = l + (r - l) / 2;
        if (isPossible(nums, mid)) {
            r = mid - 1;
        } else {
            l = mid + 1;
        }
    }
    return (double)l / 2;
}
frgthyju commented 2 years ago

抄作业

class Solution {
    public int[] sortArray(int[] nums) {
        heapSort(nums);
        return nums;
    }

    public void heapSort(int[] nums) {
        int len = nums.length - 1;
        buildMaxHeap(nums, len);
        for (int i = len; i >= 1; --i) {
            swap(nums, i, 0);
            len -= 1;
            maxHeapify(nums, 0, len);
        }
    }

    public void buildMaxHeap(int[] nums, int len) {
        for (int i = len / 2; i >= 0; --i) {
            maxHeapify(nums, i, len);
        }
    }

    public void maxHeapify(int[] nums, int i, int len) {
        for (; (i << 1) + 1 <= len;) {
            int lson = (i << 1) + 1;
            int rson = (i << 1) + 2;
            int large;
            if (lson <= len && nums[lson] > nums[i]) {
                large = lson;
            } else {
                large = i;
            }
            if (rson <= len && nums[rson] > nums[large]) {
                large = rson;
            }
            if (large != i) {
                swap(nums, i, large);
                i = large;
            } else {
                break;
            }
        }
    }

    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}
Toms-BigData commented 2 years ago

func solve(nums []int) int{ sort.Ints(nums) n := len(nums) if n <= 3 { return 0 } left := 0 right := (nums[n-1] - nums[0]) / 3 for left <= right { mid := left + (right-left)/2 if canCoverAll(mid,nums){ right = mid - 1 }else{ left = mid + 1 } } return left / 2.0 }

func canCoverAll(d int,nums []int) bool{ target := nums[0]+d n := len(nums) left,right := 0,n for left <= right{ mid := (left+right)/2 if nums[mid] > target{ right = mid - 1 }else{ left = mid + 1 } } leftBoard := left target = nums[n-1]-d for left <= right{ mid := left + (right-left)/2 if nums[mid] < target{ left = mid+1 }else{ right = mid-1 } } rightBoard := right if (rightBoard<0||nums[rightBoard]-nums[leftBoard] <= d){ return true }else{ return false } }

MissNanLan commented 2 years ago


function solve(nums) {
    console.log(nums);
    if (nums.length < 3) return 0
    nums.sort((a, b) => a - b)
    let l = 0, r = nums[nums.length - 1]
    while (l <= r) {
        const m = l + ((r - l) >>> 1)
        if (find(m, nums)) r = m - 1
        else l = m + 1
    }
    if (l > nums[nums.length - 1] || !find(l, nums)) return -1
    return l / 2
}

function find(mid, nums) {
    let range = nums[0] + mid, ligths = 0

    for (let i = 0; i < nums.length; i++) {
        if (nums[i] > range) {
            ligths += 1
            range = nums[i] + mid
        }
    }

    return ligths <= 2
}

console.log(solve([1,2,95,96,97,100]))
dahaiyidi commented 2 years ago

Problem

Minimum Light Radius

https://binarysearch.com/problems/Minimum-Light-Radius

Question 791 of 1031

++

You are given a list of integers nums representing coordinates of houses on a 1-dimensional line. You have 3 street lights that you can put anywhere on the coordinate line and a light at coordinate x lights up houses in [x - r, x + r], inclusive. Return the smallest r required such that we can place the 3 lights and all the houses are lit up.

Constraints


Note


Complexity


Python

class Solution:
    def solve(self, nums):
        # Edge cases
        if len(nums)<=3:
            return 0

        # Binary search
        nums.sort()
        low = 0
        high = (nums[-1]-nums[0]) / 3  # 直径最大值

        # 是否可以覆盖
        def can(num):
            index = 0 
            cover = nums[0]+num
            light = 1
            while index<len(nums):
                if nums[index] <= cover:
                    # 还在被照亮的范围
                    index += 1
                else:
                    #当前点已经无法被照亮
                    if light == 3:
                        # 灯的数量已经到达3了,直接返回false
                        return False
                    else:
                        # 安放新的灯,该灯最左边能照亮到 nums[index]
                        cover = nums[index]+num
                        light += 1
            # 遍历完所有的点
            return True

        while (low<high):
            middle = (low+high)//2
            if can(middle):
                high = middle
            else:
                low = middle+1
        return low/2

### C++

```C++

From : https://github.com/dahaiyidi/awsome-leetcode

chakochako commented 2 years ago
class Solution:
    def solve(self, nums):
        nums.sort()
        N = len(nums)
        if N <= 3:
            return 0
        LIGHTS = 3

        def can(diameter):
            start = nums[0]
            end = start + diameter
            for i in range(LIGHTS):
                idx = bisect_right(nums, end)
                if idx >= N:
                    return True
                start = nums[idx]
                end = start + diameter
            return False

        lo = -1
        hi = nums[-1] - nums[0]
        # Invariant: the answer lies in the interval (lo, hi]
        while lo < hi - 1:
            mid = (lo + hi) // 2
            if can(mid):
                hi = mid
            else:
                lo = mid
        return hi / 2
Okkband commented 2 years ago
class Solution:
    def solve(self, nums):
        nums.sort()
        N = len(nums)
        if N <= 3:
            return 0
        LIGHTS = 3
        # 这里使用的是直径,因此最终返回需要除以 2
        def possible(diameter):
            start = nums[0]
            end = start + diameter
            for i in range(LIGHTS):
                idx = bisect_right(nums, end)
                if idx >= N:
                    return True
                start = nums[idx]
                end = start + diameter
            return False

        l, r = 0, nums[-1] - nums[0]
        while l <= r:
            mid = (l + r) // 2
            if possible(mid):
                r = mid - 1
            else:
                l = mid + 1
        return l / 2
spacker-343 commented 2 years ago
class Solution {
    public int findRadius(int[] houses, int[] heaters) {
        Arrays.sort(houses);
        Arrays.sort(heaters);
        int radius = 0;
        int i = 0;
        for (int house : houses) {
            while (i < heaters.length && heaters[i] < house) {
                i++;
            }
            if (i == 0)
                radius = Math.max(radius, heaters[i] - house);
            else if (i == heaters.length)
                return Math.max(radius, houses[houses.length-1] - heaters[heaters.length-1]);
            else
                radius = Math.max(radius, Math.min(heaters[i] - house, house - heaters[i - 1]));
        }
        return radius;
    }
}
niuyibo0619 commented 2 years ago
class Solution:
    def solve(self, nums):
        nums.sort()
        N = len(nums)
        if N <= 3:
            return 0
        LIGHTS = 3
        # 这里使用的是直径,因此最终返回需要除以 2
        def possible(diameter):
            start = nums[0]
            end = start + diameter
            for i in range(LIGHTS):
                idx = bisect_right(nums, end)
                if idx >= N:
                    return True
                start = nums[idx]
                end = start + diameter
            return False

        l, r = 0, nums[-1] - nums[0]
        while l <= r:
            mid = (l + r) // 2
            if possible(mid):
                r = mid - 1
            else:
                l = mid + 1
        return l / 2
BpointA commented 2 years ago

思路

二分法

Python 代码


class Solution:
    def solve(self, nums):
        nums.sort()
        def check(r):
            start=nums[0]

            for i in range(3):
                end=start+r
                idx=bisect_right(nums,end)
                if idx>=len(nums):
                    return True
                start=nums[idx]
            return False

        left=0
        right=nums[-1]-nums[0]
        while left<=right:
            mid=(left+right)//2
            if check(mid):
                right=mid-1
            else:
                left=mid+1
        return left/2
fornobugworld commented 2 years ago

嵌套二分,开始题意没读懂,nums里面应该是房子坐标吧 class Solution: def solve(self, nums): nums.sort() N = len(nums) if N <= 3: return 0 LIGHTS = 3

这里使用的是直径,因此最终返回需要除以 2

    def possible(diameter):
        start = nums[0]
        end = start + diameter
        for i in range(LIGHTS):
            idx = bisect_right(nums, end)
            if idx >= N:
                return True
            start = nums[idx]
            end = start + diameter
        return False

    l, r = 0, nums[-1] - nums[0]
    while l <= r:
        mid = (l + r) // 2
        if possible(mid):
            r = mid - 1
        else:
            l = mid + 1
    return l / 2
machuangmr commented 2 years ago

代码

class Solution {
    public double solve(int[] nums) {
        Arrays.sort(nums);

        // diameter min and max
        int dMin = 0;
        int dMax = nums[nums.length - 1] - nums[0];

        int ans = 0;
        while (dMin < dMax) {
            int mid = (dMin + dMax) / 2;
            if (isValidDiameter(nums, mid)) {
                dMax = mid;
            } else {
                dMin = mid + 1;
            }
        }

        return (double)dMax / 2;
    }

    private boolean isValidDiameter(int[] nums, int d) {
        int start = nums[0];
        int end = start + d;
        int count = 1;
        for (int num : nums) {
            if (num > end) {
                if (count == 3) {
                    return false;
                } else {
                    start = num;
                    end = start + d;
                    count++;
                }
            }
        }

        return true;
    }
}
732837590 commented 2 years ago

不太理解. class Solution { public double solve(int[] nums) { Arrays.sort(nums); int n = nums.length; int left = 0, right = (nums[n - 1] - nums[0]) / 3; while(left <= right){ int mid = (left + right) / 2; if(allCovered(mid, nums)){ right = mid - 1; }else{ left = mid + 1; } } return left / 2.0; }

private boolean allCovered(int d, int[] nums){
    int target = nums[0] + d, n = nums.length;
    int left = 0, right = n - 1;
    while(left <= right){
        int mid = (left + right) / 2;
        if(nums[mid] > target){
            right = mid - 1;
        }else{
            left = mid + 1;
        }
    }
    int leftBorder = left;
    target = nums[n - 1] - d;
    left = 0;
    right = n - 1;
    while(left <= right){
        int mid = (left + right) / 2;
        if(nums[mid] < target){
            left = mid + 1;
        }else{
            right = mid - 1;
        }
    }
    int rightBorder = right;
    if(rightBorder < 0 || nums[rightBorder] - nums[leftBorder] <= d){
        return true;
    }else{
        return false;
    }
}

}

Alfie100 commented 2 years ago

题目连接: Minimum Light Radiushttps://binarysearch.com/problems/Minimum-Light-Radius

解题思路

关键点,但还没搞明白为何:每个house的坐标为int整数型,每个灯的覆盖区域也须为int整数才是最优的

  1. 排序。
  2. 二分。

代码

二分思想:

class Solution:
    def solve(self, nums):
        nums.sort()
        n = len(nums)
        if n <= 3:      # <= 3个房屋
            return 0

        def check(diameter):
            idx = 0
            for i in range(3):
                end = nums[idx] + diameter    # 灯最右端的覆盖范围
                idx = bisect.bisect_right(nums, end)   # 找出等覆盖范围内的house数目
                if idx >= n:        # 灯能够覆盖到全部的house
                    return True
            return False

        left, right = 0, nums[-1] - nums[0]
        while left < right:
            mid = (left + right) // 2
            if check(mid):      # 当前diameter取值可以覆盖3个house
                right = mid     # 则diameter可适当取小一些再试探
            else:               # 当前diameter取值过小,则可增大diameter继续试探
                left = mid + 1
        return left/2       # 最终的left=right即为最终的diameter,除以2即为所要求的最小radius

复杂度分析

for123s commented 2 years ago
class Solution {
    public int[] sortArray(int[] nums) {
        heapSort(nums);
        return nums;
    }

    public void heapSort(int[] nums) {
        int len = nums.length - 1;
        buildMaxHeap(nums, len);
        for (int i = len; i >= 1; --i) {
            swap(nums, i, 0);
            len -= 1;
            maxHeapify(nums, 0, len);
        }
    }

    public void buildMaxHeap(int[] nums, int len) {
        for (int i = len / 2; i >= 0; --i) {
            maxHeapify(nums, i, len);
        }
    }

    public void maxHeapify(int[] nums, int i, int len) {
        for (; (i << 1) + 1 <= len;) {
            int lson = (i << 1) + 1;
            int rson = (i << 1) + 2;
            int large;
            if (lson <= len && nums[lson] > nums[i]) {
                large = lson;
            } else {
                large = i;
            }
            if (rson <= len && nums[rson] > nums[large]) {
                large = rson;
            }
            if (large != i) {
                swap(nums, i, large);
                i = large;
            } else {
                break;
            }
        }
    }

    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}
stackvoid commented 2 years ago

思路

看不太懂

代码

class Solution {
    public int flipgame(int[] fronts, int[] backs) {
        Set<Integer> same = new HashSet();
        for (int i = 0; i < fronts.length; ++i)
            if (fronts[i] == backs[i])
                same.add(fronts[i]);
        int ans = 9999;
        for (int x : fronts)
            if (!same.contains(x))
                ans = Math.min(ans, x);
        for (int x : backs)
            if (!same.contains(x))
                ans = Math.min(ans, x);
        return ans % 9999;
    }
}

复杂度分析

O(NLongN) O(N)

baddate commented 2 years ago
int need(vector<int>& nums, double r) {
    int ans = 0;
    for (int i = 0; i < nums.size();) {
        ans++;
        int right = nums[i] + 2 * r;
        i = upper_bound(nums.begin(), nums.end(), right) - nums.begin();
    }
    return ans;
}

double solve(vector<int>& nums) {
    if (nums.size() <= 3) return 0;
    sort(nums.begin(), nums.end());
    int N = nums.size();
    double l = 0, r = nums.back() - nums.front();
    for (int i = 0; i < 32; i++) {
        double mid = (l + r) / 2;
        if (need(nums, mid) <= 3)
            r = mid;
        else
            l = mid;
    }
    return r;
}
kbfx1234 commented 2 years ago

Minimum Light Radius

// 补打卡
bool help(vector<int>& nums, int mid) {
    int start = nums[0];
    int end = start + mid;
    for (int i = 0; i < 3; i++) {
        int idx = 0;
        while (nums[idx] <= end) idx++;
        if (idx >= nums.size()) return true;
        start = nums[idx];
        end = start + mid;
    }
    return false;
}

double solve(vector<int>& nums) {
    if (nums.size() < 3) return 0;
    sort(nums.begin(), nums.end());
//  left right
    int l = 0;
    int r = nums[nums.size()-1] - nums[0];
    while (l <= r) {
        int mid = l + (r - l) / 2;
        if (help(nums, mid)) {
            r = mid - 1;
        }
        else {
            l = mid + 1;
        }
    }
    return (double) l / 2;
}
tian-pengfei commented 2 years ago
class Solution {
public:
//    本体可以抽象成寻找里热源最远距离的点
    int findRadius(vector<int>& houses, vector<int>& heaters) {
        sort(houses.begin(),houses.end());
        sort(heaters.begin(),heaters.end());
        int ans = 0;
        for (auto const & val:houses){
            int r = needRadius(val,heaters);
            ans = max(r,ans);
        }

        return ans;

    }

    int needRadius(int val,vector<int>& heater){
        if(val>=heater.back())return val-heater.back();
        if(val<=heater.front())return heater.front()-val;

        int left =  0;
        int right = heater.size()-1;
        while (true){
            int mid = long (left+right)/2;
            if(heater[mid]<val){
                left = mid+1;
            }else if (heater[mid]==val){
                return 0;
            }else{
                if(heater[mid-1]<=val){
                    return min(val-heater[mid-1],heater[mid]-val);
                }else{
                    right = mid-1;
                }
            }
        }

        return 0;
    }
};