错误解法:思路一看就不对,步骤太繁杂了
public class Solution {
public int findRadius(int[] houses, int[] heaters) {
int radius = 0;
//从houses[0]到heaters[0]
radius = Math.abs(houses[0] - heaters[0]);
//中间部分
for(int i = 0; i < heaters.length - 1; i++){
int left = heaters[i];
int right = heaters[i+1];
int mid = mid = left + (right - left) / 2;
/*if((right - left) % 2 == 0){
mid = left + (right - left) / 2;
} else {
mid = left + (right - left) / 2 + 1;
}*/ //??? heaters = {1,6}时有问题
//从left到mid
int j = 0;
for(j = 0; j < houses.length && houses[j] <= mid; j++);
if(j == houses.length){
radius = Math.max(radius, Math.abs(houses[houses.length-1] - left));//减去Left而不是mid,Mid用来判断半径
} else if(j == 0){
radius = Math.max(radius, Math.abs(houses[0] - left));
} else {
radius = Math.max(radius, Math.abs(houses[j - 1] - left));
}
//从mid+1到right
for(j = 0; j < houses.length && houses[j] <= right; j++);
if(j == houses.length){
radius = Math.max(radius, Math.abs(houses[houses.length-1] - mid - 1));//减去(mid+1)而不是right,right用来判断半径
} else if(j == 0){
radius = Math.max(radius, Math.abs(houses[0] - mid - 1));
} else {
radius = Math.max(radius, Math.abs(houses[j - 1] - mid - 1));
}
}
//从heaters[end]到houses[end]
radius = Math.max(radius, Math.abs(houses[houses.length-1] - heaters[heaters.length-1]));
return radius;
}
}
解法一:
public class Solution {
public int findRadius(int[] houses, int[] heaters) {
//既然是计算火炉能让每个房子都被温暖到的半径,那么就从房子出发,找出火炉
//先将房子和火炉排序
Arrays.sort(houses);
Arrays.sort(heaters);
//对于每一个房子,分别计算出在它左边的火炉,和在它右边的火炉到它的距离,取出最小值作为该房子能被温暖到所需的距离
//取出每一个房子能被温暖到的最大距离作为半径
//临界条件,有的房子可能没有左边的火炉或者右边的火炉
//Arrays.binarySearch(int[]a, int key) 这个函数可以找出key在数组a中的具体位置
/*总结:binarySearch()方法的返回值为:
* 1、如果找到关键字,则返回值为关键字在数组中的位置索引,且索引从0开始
* 2、如果没有找到关键字,返回值为负的插入点值,所谓插入点值就是第一个比关键字大的元素在数组中的位置索引,而且这个位置索引从1开始。
注意:调用binarySearch()方法前要先调用sort方法对数组进行排序,否则得出的返回值不定,这时二分搜索算法决定的。
*
* 对于数组[4, 6, 10, 21, 25, 95]
* 关键字2的返回值为:-1
* 关键字20的返回值为:-4
* 关键字30的返回值为:-6
* 关键字100的返回值为:-7
* 关键字10的返回值为:2
*
* 关键字2并没有在数组中,而且2比数组中的任何一个元素都小,所以其插入点的值应为元素4的位置也就是1(没有找到关键字从1开始)
关键字20也不在数组中,数组中第一个比20大的数是21,所以20的插入点值为4(没用找到关键字从索引从1开始)
关键字100也不在数组中,而且100比数组中所有的元素都大,此时插入点值为length+1 为7(没有找到关键字索引从1开始)
关键字10在数组中,所以返回其在数组中的索引为2(找到关键字索引从0开始)
*/
int res = 0;
for(int house : houses){
int index = Arrays.binarySearch(heaters, house);
if(index < 0){//说明没找到元素
//调整index,方便找出每一个房子的左右火炉
index = -(index + 1);//都让index指向房子的右火炉处,如果相等,那么和右火炉的距离就是0
}
int distLeft = index - 1 >= 0 ? house - heaters[index - 1] : Integer.MAX_VALUE;
int distRight = index < heaters.length ? heaters[index] - house : Integer.MAX_VALUE;
int dist = Math.min(distLeft, distRight);
res = Math.max(res, dist);
}
return res;
}
}
解法二:
public class Solution {
public int findRadius(int[] houses, int[] heaters) {
//既然是计算火炉能让每个房子都被温暖到的半径,那么就从房子出发,找出火炉
//先将房子和火炉排序
Arrays.sort(houses);
Arrays.sort(heaters);
//对于每一个房子,分别计算出在它左边的火炉,和在它右边的火炉到它的距离,取出最小值作为该房子能被温暖到所需的距离
//取出每一个房子能被温暖到的最大距离作为半径
int j = 0;
int res = 0;
for(int house : houses){
while (j < heaters.length - 1 ){
//此时计算找到了距离该房子的最近的火炉heaters[j]
if(Math.abs(heaters[j + 1] - house) > Math.abs(heaters[j] - house)){
break;
}
j++;
}
int dist = Math.abs(heaters[j] - house);
res = Math.max(res, dist);
}
return res;
}
}