leetcode[Heaters]

错误解法:思路一看就不对,步骤太繁杂了

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;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值