1. 程式人生 > >Heaters 供暖器

Heaters 供暖器

冬季已經來臨。 你的任務是設計一個有固定加熱半徑的供暖器向所有房屋供暖。

現在,給出位於一條水平線上的房屋和供暖器的位置,找到可以覆蓋所有房屋的最小加熱半徑。

所以,你的輸入將會是房屋和供暖器的位置。你將輸出供暖器的最小加熱半徑。

說明:

  1. 給出的房屋和供暖器的數目是非負數且不會超過 25000。
  2. 給出的房屋和供暖器的位置均是非負數且不會超過10^9。
  3. 只要房屋位於供暖器的半徑內(包括在邊緣上),它就可以得到供暖。
  4. 所有供暖器都遵循你的半徑標準,加熱的半徑也一樣。

示例 1:

輸入: [1,2,3],[2]
輸出: 1
解釋: 僅在位置2上有一個供暖器。如果我們將加熱半徑設為1,那麼所有房屋就都能得到供暖。

示例 2:

輸入:
[1,2,3,4],[1,4] 輸出: 1 解釋: 在位置1, 4上有兩個供暖器。我們需要將加熱半徑設為1,這樣所有房屋就都能得到供暖。

思路:

首先對輸入的兩個陣列進行由小到大排序,然後每次找到house[i]對應的heat的包含範圍(最近的包含範圍,即heat[j]<=house[i]<=heat[j+1]),然後計算house[i]離左近還是右近,取其中最小的距離,這樣遍歷完一遍house陣列後,每個house[i]都對應一組距離,取所有house陣列中距離的最大值即使答案。具體思路可以用hashmap<int,hashset>儲存,但是這樣太麻煩,在參考了discuss部分的程式碼發現可以不需要O(n)的輔助空間,只需要O(1)即可。每次遍歷過程中更新res,並且由於house和heat都已經排序,每次查詢不需要從頭查詢,類似於歸併查詢中的合併步驟來一次遍歷house和heat便可以達到完成。

    int findRadius(vector<int>& houses, vector<int>& heaters) {
	sort(houses.begin(), houses.end());
	sort(heaters.begin(), heaters.end());
	int res=0;
	int j = 0;
	for (int i = 0; i < houses.size(); i++) {
		int tmp = houses[i];
		while (j < (heaters.size() - 1) && abs(heaters[j] - tmp) >= abs(heaters[j + 1] - tmp)) {
			j++;
		}
		res = max(res, abs(heaters[j] - tmp));
	}
	return res;        
    }
其中的
abs(heaters[j] - tmp) >= abs(heaters[j + 1] - tmp)

等於符號必須要有,主要是對應如下的情況:

house:[1,2,2,4,5]
heat: [1,2,2,4,5]

大家自己debug便可以看出如果沒有等號會出現錯位的情況,導致答案錯誤。