475. Heaters

题目链接:https://leetcode.com/problems...

现在easy题都这个风格了额,感觉有medium的难度。。
首先sort两个数组。之后如果找到最小的radius,开始想到的是用2 points。一个i指house的位置,另一个j指向heater,循环的invariant是:house[0, i]已被heater[0, j]覆盖,现在来看house[i],如果

  1. 在(heater[j] - radius, heater[j] + radius)之间,则更新i++

  2. 如果不在,比较abs(heater[j] - house[i])和abs(heater[j+k] - house[i])找到小的那个更新radius,如果abs(heater[j+k] - house[i])小,则更新j+=k, i++

看tag是binary search,这里就是对每一个house的位置,binary search离它最近的两边的heater,然后取距离小的那个更新结果。

public class Solution {
    public int findRadius(int[] houses, int[] heaters) {
        // sort
        Arrays.sort(houses);
        Arrays.sort(heaters);

        int j = 0;
        int radius = 0;
        for(int house : houses) {
            if(Math.abs(heaters[j] - house) <= radius) continue;
            // if not in radius, update radius
            int local = Math.abs(heaters[j] - house);
            // find the j gives the smallest local radius
            while(j + 1 < heaters.length && Math.abs(heaters[j+1] - house) <= local) {
                local = Math.abs(heaters[j+1] - house);
                j++;
            }
            radius = Math.max(local, radius);
        }
        
        return radius;
    }
}

binary search:

public class Solution {
    public int findRadius(int[] houses, int[] heaters) {
        // sort
        Arrays.sort(houses);
        Arrays.sort(heaters);

        int radius = 0;
        for(int house : houses) {
            int local = binarySearch(heaters, house);
            radius = Math.max(radius, local);
        }
        
        return radius;
    }
    
    private int binarySearch(int[] heaters, int target) {
        int l = 0, r = heaters.length - 1;
        while(l + 1 < r) {
            int mid = l + (r - l) / 2;
            if(heaters[mid] == target) return 0;
            else if(heaters[mid] < target) l = mid;
            else r = mid;
        }
        return Math.min(Math.abs(target - heaters[l]), Math.abs(target - heaters[r]));
    }
}

lulouch13
13 声望6 粉丝