mirror of
https://github.com/ShusenTang/LeetCode.git
synced 2024-09-02 14:20:01 +00:00
96 lines
3.5 KiB
Markdown
96 lines
3.5 KiB
Markdown
# [475. Heaters](https://leetcode.com/problems/heaters/description/)
|
||
# 思路
|
||
计算每一个house与其最近heater的距离dist,在计算所有house的dist的最大值即所求。针对如何求每一个house的dist,有三种思路。
|
||
## 思路一
|
||
将heater排序,对与每一个house h,在heaters中二分查找h,若能找到则dist=0,否则dist应该是h与最接近的heater的距离。
|
||
时间复杂度O(n * nlogn), 空间复杂度O(1)
|
||
## 思路二
|
||
思路类似一,只是不自己写二分查找,而是使用stl中的lower_bound函数进行查找。
|
||
lower_bound(begin_it, end_it, target)返回的是处于两个迭代器begin_it和end_it之间(左闭右开)的元素中不小于target的最小元素的迭代器。若不存在返回end_it.
|
||
> 注意:begin_it到end_it的元素需有序
|
||
|
||
复杂度同思路一
|
||
|
||
|
||
## 思路三*
|
||
如果houses和heaters都是有序的话,其实不用每次都二分查找, 而只需要遍历一次就行了。这是因为我们注意到一个事实:
|
||
若离house h最近的heater为ht,那么离下一个house最近的heater的位置大小肯定不小于ht,所以不用回溯ht。
|
||
时间复杂度O(n^2), 空间复杂度O(1)
|
||
|
||
# C++
|
||
## 思路一
|
||
```
|
||
class Solution {
|
||
private:
|
||
int find_max_dist(vector<int>&sorted_heaters, int &h){ # 二分查找h
|
||
int low = 0, high = sorted_heaters.size() - 1, mid;
|
||
while(low <= high){
|
||
mid = low + (high - low) / 2;
|
||
if(sorted_heaters[mid] == h) return 0; // 找到
|
||
if(sorted_heaters[mid] < h) low = mid + 1;
|
||
else high = mid - 1;
|
||
}
|
||
// 没找到,计算最小dist
|
||
if(high < 0) return sorted_heaters[low] - h;
|
||
else if(low >= sorted_heaters.size()) return h - sorted_heaters[high];
|
||
else return min(sorted_heaters[low] - h, h - sorted_heaters[high]);
|
||
}
|
||
|
||
public:
|
||
int findRadius(vector<int>& houses, vector<int>& heaters) {
|
||
sort(heaters.begin(), heaters.end());
|
||
int res = 0;
|
||
for(int h: houses)
|
||
res = max(res, find_max_dist(heaters, h));
|
||
return res;
|
||
|
||
}
|
||
};
|
||
```
|
||
## 思路二
|
||
```
|
||
class Solution {
|
||
private:
|
||
int find_max_dist(vector<int>&sorted_heaters, int &h){
|
||
auto larger = lower_bound(sorted_heaters.begin(), sorted_heaters.end(), h); // 返回的是一个迭代器
|
||
if(larger == sorted_heaters.end()) return h - *(larger - 1);
|
||
else if(larger == sorted_heaters.begin()) return *larger - h;
|
||
else return min(*larger - h, h - *(larger - 1));
|
||
}
|
||
public:
|
||
int findRadius(vector<int>& houses, vector<int>& heaters) {
|
||
sort(heaters.begin(), heaters.end()); # 传入lower_bound的必须是有序的
|
||
int res = 0;
|
||
for (int h: houses) {
|
||
res = max(res, find_max_dist(heaters, h));
|
||
}
|
||
return res;
|
||
|
||
}
|
||
};
|
||
```
|
||
## 思路三*
|
||
```
|
||
class Solution {
|
||
public:
|
||
int findRadius(vector<int>& houses, vector<int>& heaters) {
|
||
if (heaters.size() == 0) {
|
||
return 0;
|
||
}
|
||
sort(houses.begin(), houses.end());
|
||
sort(heaters.begin(), heaters.end());
|
||
int res = 0;
|
||
int ht = 0;
|
||
for (int h: houses) {
|
||
// 找到离h最近的heater,这个heater肯定位于当前heater的右边(或就是当前heater)
|
||
while (ht + 1 < heaters.size() && (abs(heaters[ht + 1] - h) <= abs(heaters[ht] - h))) {
|
||
ht++;
|
||
}
|
||
res = max(res, abs(heaters[ht] - h));
|
||
}
|
||
return res;
|
||
|
||
}
|
||
};
|
||
```
|