二分法

  • 475. 供暖器
  • 方法一:二分查找
  • 方法二:滑动窗口


475. 供暖器

Leetcode 在加热站中找到每个房屋需要的最小半径的最大值

方法一:二分查找

class Solution {
    public int findRadius(int[] houses, int[] heaters) {
        Arrays.sort(heaters);
        int res = 0, n = heaters.length;
        for (int h: houses){
            int left = 0, right = n;
            while (left < right){
                int mid = left + (right - left) / 2;
                if (h > heaters[mid]) left = mid + 1;
                else right = mid;
            }

            int dist1 = right == 0 ? Integer.MAX_VALUE : h - heaters[right - 1];
            int dist2 = right == n ? Integer.MAX_VALUE : heaters[right] - h; 
            res = Math.max(res, Math.min(dist1, dist2));
        }
        return res;
    }
}

方法二:滑动窗口

class Solution {
    public int findRadius(int[] houses, int[] heaters) {
        Arrays.sort(houses);
        int n = heaters.length;
        int [] heat = Arrays.copyOf(heaters, n + 2);        
        heat[n] = -1000000000; // Integer.MIN_VALUE 会越界,添加哨兵
        heat[n + 1] = Integer.MAX_VALUE;
        Arrays.sort(heat);

        int i = 0, ans = 0;
        
        for (int h: houses){         
        	// 找 h 右边第一个热站(刚好 > h), i - 1 是左边的第一个或正好是 h  
        	// h 后面的不可能使用 i-1 前面的热站,所以从 i 继续循环。 [heaters[i-1], heaters[i]] 滑动窗口  
            while (heat[i] <= h) i++;                
            ans = Math.max(ans, Math.min(h - heat[i-1], heat[i] - h));
        }
        return ans;
    }
}