博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[LeetCode] Heaters 加热器
阅读量:5079 次
发布时间:2019-06-12

本文共 3745 字,大约阅读时间需要 12 分钟。

 

Winter is coming! Your first job during the contest is to design a standard heater with fixed warm radius to warm all the houses.

Now, you are given positions of houses and heaters on a horizontal line, find out minimum radius of heaters so that all houses could be covered by those heaters.

So, your input will be the positions of houses and heaters seperately, and your expected output will be the minimum radius standard of heaters.

Note:

  1. Numbers of houses and heaters you are given are non-negative and will not exceed 25000.
  2. Positions of houses and heaters you are given are non-negative and will not exceed 10^9.
  3. As long as a house is in the heaters' warm radius range, it can be warmed.
  4. All the heaters follow your radius standard and the warm radius will the same.

 

Example 1:

Input: [1,2,3],[2]Output: 1Explanation: The only heater was placed in the position 2, and if we use the radius 1 standard, then all the houses can be warmed.

 

Example 2:

Input: [1,2,3,4],[1,4]Output: 1Explanation: The two heater was placed in the position 1 and 4. We need to use radius 1 standard, then all the houses can be warmed.

 

这道题是一道蛮有意思的题目,首先我们看题目中的例子,不管是houses还是heaters数组都是有序的,所以我们也需要给输入的这两个数组先排序,以免其为乱序。我们就拿第二个例子来分析,我们的目标是houses中的每一个数字都要被cover到,那么我们就遍历houses数组,对每一个数组的数字,我们在heaters中找能包含这个数字的左右范围,然后看离左右两边谁近取谁的值,如果某个house位置比heaters中最小的数字还小,那么肯定要用最小的heater去cover,反之如果比最大的数字还大,就用最大的数字去cover。对于每个数字算出的半径,我们要取其中最大的值。通过上面的分析,我们就不难写出代码了,我们在heater中两个数一组进行检查,如果后面一个数和当前house位置差的绝对值小于等于前面一个数和当前house位置差的绝对值,那么我们继续遍历下一个位置的数。跳出循环的条件是遍历到heater中最后一个数,或者上面的小于等于不成立,此时heater中的值和当前house位置的差的绝对值就是能cover当前house的最小半径,我们更新结果res即可,参见代码如下:

 

解法一:

class Solution {public:    int findRadius(vector
& houses, vector
& heaters) { int n = heaters.size(), j = 0, res = 0; sort(houses.begin(), houses.end()); sort(heaters.begin(), heaters.end()); for (int i = 0; i < houses.size(); ++i) { int cur = houses[i]; while (j < n - 1 && abs(heaters[j + 1] - cur) <= abs(heaters[j] - cur)) { ++j; } res = max(res, abs(heaters[j] - cur)); } return res; }};

 

还是上面的思路,我们可以用二分查找法来快速找到第一个大于等于当前house位置的数,如果这个数存在,那么我们可以算出其和house的差值,并且如果这个数不是heater的首数字,我们可以算出house和前面一个数的差值,这两个数中取较小的为cover当前house的最小半径,然后我们每次更新结果res即可,参见代码如下:

 

解法二:

class Solution {public:    int findRadius(vector
& houses, vector
& heaters) { int res = 0, n = heaters.size(); sort(heaters.begin(), heaters.end()); for (int house : houses) { int left = 0, right = n; while (left < right) { int mid = left + (right - left) / 2; if (heaters[mid] < house) left = mid + 1; else right = mid; } int dist1 = (right == n) ? INT_MAX : heaters[right] - house; int dist2 = (right == 0) ? INT_MAX : house - heaters[right - 1]; res = max(res, min(dist1, dist2)); } return res; }};

 

我们可以用STL中的lower_bound来代替二分查找的代码来快速找到第一个大于等于目标值的位置,其余部分均和上面方法相同,参见代码如下:

 

解法三:

class Solution {public:    int findRadius(vector
& houses, vector
& heaters) { int res = 0; sort(heaters.begin(), heaters.end()); for (int house : houses) { auto pos = lower_bound(heaters.begin(), heaters.end(), house); int dist1 = (pos == heaters.end()) ? INT_MAX : *pos - house; int dist2 = (pos == heaters.begin()) ? INT_MAX : house - *(--pos); res = max(res, min(dist1, dist2)); } return res; }};

 

参考资料:

 

转载于:https://www.cnblogs.com/grandyang/p/6181626.html

你可能感兴趣的文章
@Column标记持久化详细说明
查看>>
创建本地yum软件源,为本地Package安装Cloudera Manager、Cloudera Hadoop及Impala做准备...
查看>>
mysql8.0.13下载与安装图文教程
查看>>
站立会议08(冲刺2)
查看>>
url查询参数解析
查看>>
http://coolshell.cn/articles/10910.html
查看>>
[转]jsbsim基础概念
查看>>
DIV和SPAN的区别
查看>>
第一次使用cnblogs
查看>>
C#语法糖之 session操作类 asp.net
查看>>
2015 Multi-University Training Contest 3
查看>>
使用Gitblit 在windows 上部署你的Git Server
查看>>
获取文件编码格式
查看>>
XPO学习(1)----第一个基于XPO的 数据感知应用程序
查看>>
Django-DjangoUeditor
查看>>
MongoDB in Action (MongoDB 实战).pdf
查看>>
Oracle常用SQL与练习
查看>>
spring注解
查看>>
python中random库的使用
查看>>
cheerio 服务器端的jquery
查看>>