问题描述
我正在尝试遵循leetcode加热器问题(容易实现)。
我写了一个无效的算法(我意识到自己做错了),所以我去讨论了解决方案。
我偶然发现使用二进制搜索的人,但无法理解他们的逻辑。 有人可以向我解释一下(算法)如何使用二进制搜索解决此问题(谷歌搜索没有任何帮助)
这是我的非二进制搜索算法,不起作用
/**
* @param {number[]} houses
* @param {number[]} heaters
* @return {number}
*/
var findRadius = function(houses,heaters) {
let maximumDist = 1
let currentDist = i = cHeaterIndex = 0
while (i<houses.length){
const cHeaterPosition = heaters[cHeaterIndex]
if (houses[i] === cHeaterPosition || i === houses.length-1) {
if (houses[i] === cHeaterPosition) {
if (maximumDist < currentDist) {
maximumDist = parseInt((currentDist - 1)/2)
}
} else {
maximumDist = currentDist - 1
}
currentDist = 1
cHeaterIndex++
}
i++
currentDist++
}
return maximumDist
};
解决方法
二进制搜索背后的逻辑是:
找到最适合特定房屋的加热器的左右位置。 现在,考虑一下,如果给我们排序后的数字,而您必须找到一个值,那么您将使用二进制搜索。
这里同样,您将获得根据加热器位置排序的数字,并且搜索值是特定的房屋位置。现在,您必须找到最接近该房屋位置的加热器位置值索引。
示例:
加热器[] = {1,2,3,8} house_position = 5。
因此,加热器的从左起最接近的值为3(索引= 2),我们可以通过二进制搜索找到该值。现在,这是可以加热房屋的加热器的左侧位置。位置正确的加热器还可以加热位于下一个索引(索引= 3),其值为8的房屋。因此,可以通过位置3和8的两个加热器对这个特定的房屋进行加热。从中我们可以找到最佳的加热器位置与房屋的距离最小(因为半径最小)。在这种情况下,加热器位于位置3(index = 2),与房屋的距离为2。
这是对该问题进行二进制搜索的逻辑。
这是相同的工作示例(JAVA代码)。
/**
* @param {number[]} houses
* @param {number[]} heaters
* @return {number}
*/
var findRadius = function(houses,heaters) {
var totalhouses = houses.length,totalheaters = heaters.length,index=0,currindex=0,max = 0,currmin;
heaters.sort((a,b) => a - b);
while(index< totalhouses) {
currindex = search(heaters,houses[index],10);
if(currindex==-1) { //if left positioned heater is not present
currmin = heaters[0] - houses[index];
} else {
if(currindex+1 < totalheaters) {
currmin = Math.min(heaters[currindex+1] - houses[index],houses[index] - heaters[currindex]);
} else { //if right positioned heater is not present
currmin = houses[index] - heaters[currindex];
}
}
max = Math.max(max,currmin);
index++;
}
return max;
};
var search = function(heaters,value) { //binary search to find best possible left positioned heater for the house
var start=0,end = heaters.length-1,mid=0;
while(start<=end) {
mid = Math.floor((start + end) / 2);
if(heaters[mid] == value){
return mid;
} else if(heaters[mid] > value) {
end = mid-1;
} else {
start = mid+1;
}
}
return end;
}