https://leetcode-cn.com/problems/heaters/comments/
冬季已经来临。 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖。
现在,给出位于一条水平线上的房屋和供暖器的位置,找到可以覆盖所有房屋的最小加热半径。
所以,你的输入将会是房屋和供暖器的位置。你将输出供暖器的最小加热半径。
说明:
给出的房屋和供暖器的数目是非负数且不会超过 25000。
给出的房屋和供暖器的位置均是非负数且不会超过10^9。
只要房屋位于供暖器的半径内(包括在边缘上),它就可以得到供暖。
所有供暖器都遵循你的半径标准,加热的半径也一样。
示例 1:
输入: [1,2,3],[2]
输出: 1
解释: 仅在位置2上有一个供暖器。如果我们将加热半径设为1,那么所有房屋就都能得到供暖。
示例 2:
输入: [1,2,3,4],[1,4]
输出: 1
解释: 在位置1, 4上有两个供暖器。我们需要将加热半径设为1,这样所有房屋就都能得到供暖。
/*
思路:
先排序--快排
对于每个房屋,要么用前面的供暖,要么用后面的供暖,每个房屋取最小值,半径即为所有最小值中的最大值
*/
void quick_sort(int *arr, int start, int end){
if(start >= end){
return;
}
int i = start;
int j = end;
while(i < j){
while(arr[j] >= arr[start] && i < j){ // 先从后面走!!!
j--;
}
while(arr[i] <= arr[start] && i < j){
i++;
}
if(i < j){
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
// 交换基准值
int tmp = arr[i];
arr[i] = arr[start];
arr[start] = tmp;
quick_sort(arr, start, i - 1);
quick_sort(arr, i + 1, end);
}
int __binary_search(int *heaters, int len, int val, int *ret){ // 返回下标值
int lo = 0;
int hi = len - 1; // 使用对称边界
while(lo <= hi){
int mid = lo + (hi - lo) / 2; //找中间值
if(val > heaters[mid]){
lo = mid + 1;
}
else if(heaters[mid] == val){
return 0;
}
else if(val < heaters[mid]){
hi = mid - 1;
}
}
*ret = lo; // 如果没有找到记录中间值,此时lo>hi;
return -1;
}
int find_min(int val, int *heaters, int heatersSize){
int i = 0;
bool small_flag = false;
int small_mark = 0;
bool big_flag = false;
int big_mark = 0;
int *ret_i = (int *)calloc(1, sizeof(int));
int ret = __binary_search(heaters, heatersSize, val, ret_i);
if(0 == ret) return 0; // 判断该房子是否有供暖器,有最短为0
if(val > heaters[0]) small_flag = true; // 判断是否有前置供暖
if(val < heaters[heatersSize - 1]) big_flag = true; // 判断是否有后置供暖
small_mark = *ret_i - 1;
big_mark = *ret_i;
free(ret_i);
// 算最小半径
int d_small = 0;
int d_big = 0;
if(small_flag && !big_flag){
d_small = val - heaters[small_mark];
return d_small;
}
if(!small_flag && big_flag){
d_big = heaters[big_mark] - val;
return d_big;
}
d_small = val - heaters[small_mark];
d_big = heaters[big_mark] - val;
return d_small < d_big ? d_small : d_big;
}
int findRadius(int* houses, int housesSize, int* heaters, int heatersSize) {
quick_sort(houses, 0 ,housesSize - 1);
quick_sort(heaters, 0, heatersSize - 1);
int i = 0;
int j = 0;
int ret = 0;
for(; i < housesSize; i++){
int val = find_min(houses[i], heaters, heatersSize);
ret = ret > val ? ret : val;
}
return ret;
}