LeetCode/solutions/475. Heaters.md

96 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# [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;
}
};
```