From 4013443f00b7a745161e78531d1c4f415175406d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=90=E6=A0=91=E6=A3=AE?= <14021051@buaa.edu.cn> Date: Fri, 12 Oct 2018 17:24:10 +0800 Subject: [PATCH] Create 475. Heaters.md --- 475. Heaters.md | 95 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 475. Heaters.md diff --git a/475. Heaters.md b/475. Heaters.md new file mode 100644 index 0000000..93b7a62 --- /dev/null +++ b/475. Heaters.md @@ -0,0 +1,95 @@ +# [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&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& houses, vector& 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&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& houses, vector& 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& houses, vector& 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; + + } +}; +```