供暖器[看问题角度 + 二分 + 双指针]

前言

紧密关联有序 + 找元素 + 二分,能够降低时间复杂度,甚至是解题。多练题,找到题感才能找到看问题的角度,对细节的处理也会更加得心应手,而不是死知识点,见招拆招的能力会更强。

一、供暖器

在这里插入图片描述

二、二分 || 双指针

1、二分寻找

// 供暖器
public class FindRadius {
    /*
    角度没对,角度没题感 + 角度较乱。
    以前:两个空调之间的距离 / 2,错了。
    题解:想要每个房间都被覆盖,且求最小覆盖,应该看每个房间离得最近的空调,然后记录值,对于所有房间,记录最大值即可。
    idea:为了便于寻找空调,所以对空调位置排序,采用二分寻找。
     */
    public int findRadius(int[] houses, int[] heaters) {
        Arrays.sort(heaters);

        int max = 0;
        for (int h : houses) max = Math.max(max, binarySearch(heaters, h));

        return max;
    }

    public int binarySearch(int[] heaters, int target) {
        int low = 0, high = heaters.length;

        while (low < high) {
            int mid = low + (high - low >> 1);
            int midVal = heaters[mid];

            if (midVal > target) high = mid;
            else low = mid + 1;
        }
        if (low == heaters.length) return target - heaters[low - 1];
        if (low == 0) return heaters[0] - target;
        return Math.min(Math.abs(target - heaters[low - 1]), Math.abs(target - heaters[low]));
    }
}

2、双指针

// 一旦明确了题目要求和看题角度,那么可使用其他方法进行解答。
class FindRadius2 {
    /*
    角度没对,角度没题感 + 角度较乱。
    以前:两个空调之间的距离 / 2,错了。
    题解:想要每个房间都被覆盖,且求最小覆盖,应该看每个房间离得最近的空调,然后记录值,对于所有房间,记录最大值即可。
    idea:可以对房子位置和空调位置都排序,同时遍历,求每个房子最近的供暖器。
     */
    public int findRadius(int[] houses, int[] heaters) {
        Arrays.sort(houses);
        Arrays.sort(heaters);

        int max = 0, idx = 0;
        for (int h : houses) {

            // bug1:有重复房间,要寻找最近的哪一个。
            // bug2:最后一个空调了,就不能往下找了。
            while (idx < heaters.length - 1 && heaters[idx] < h) ++idx;

            int m = Math.abs(h - heaters[idx]);
            int n = idx == 0 ? Integer.MAX_VALUE : h - heaters[idx - 1];

            max = Math.max(max, Math.min(m, n));
        }
        return max;
    }
}

总结

1)看问题角度正确,影响着是否能够解题,而题量产生的题感对看问题的角度也有很大的影响。

2)紧密关联有序 + 找元素 + 二分,相互联系,相互提醒。

3)题要多练,因为很多题不是刚好嵌入一个知识点,而是四邻八脚,就会体现出很多细节,需要有见招拆招的能力,才能解题。这应该是通常讲的debug部分吧,一些边界/重复等等辅助因素导致的错误。

参考文献

[1] LeetCode 供暖器

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值