剑指Offer题目笔记20(在数组范围内二分查找)

面试题72:

面试题72

问题:

​ 输入一个非负整数,计算它的平方根。

解决方案:
  1. 使用二分查找。一个数x的平方根一定小于或等于x,同时,除了0之外的所有非负整数的平方根都大于等于1,故该数的平方根在1到x的范围内。
  2. 定义left为1作为左边界,right为x作为右边界。取该范围内的中间数字m,并判断m是否小于x/m,如果m小于x/m,那么继续判断(m+1)是否大于x/(m+1),如果(m+1)大于x/(m+1),那么返回m,如果(m+1)不大于x/(m+1),那么目标值位于数组后半部分。如果m大于或等于x/m,那么目标值位于数组前半部分。
源代码:
class Solution {
    public int mySqrt(int x) {
        int left = 1;
        int right = x;
        while(left <= right){
            int mid = (left + right)/2;
            //
            if(mid <= x/mid){
                if(mid + 1 > x/(mid + 1)){
                    return mid;
                }

                left = mid + 1;
            }else{
                right = mid - 1;
            }
        }

        return 0;
    }
}

面试题73:

面试题73

问题:

​ 门卫走开H小时,有n堆香蕉,狒狒去吃香蕉,狒狒一个小时只能吃一堆香蕉,狒狒要在门卫回来前将香蕉吃完,问狒狒每个小时至少得吃多少根香蕉。

解决方案:
  1. 使用二分查找。狒狒吃香蕉的速度的范围在1和数组中的最大值(也就是n堆香蕉的最大值)记为max根。
  2. 在1-max中取中间值mid,求出按照每个小时吃mid根的速度吃完n堆香蕉需要多少小时记为time1,如果time1小于或等于H,那么继续判断mid是否为1,如果是,那么mid就是狒狒每小时吃香蕉速度的最小值。如果mid不为1,那么继续判断以mid-1求出的时间time2与H,如果time2大于H,那么mid就是狒狒每小时吃香蕉速度的最小值。如果time2小于H,那么狒狒吃香蕉的速度还可以慢点。如果time1大于H,那么狒狒吃香蕉的速度应该快些。
源代码:
class Solution {
    public int minEatingSpeed(int[] piles, int h) {
        int left = 1;
        int right = Integer.MIN_VALUE;
        for (int pile : piles) {
            right = Math.max(right, pile);
        }
        while (left <= right) {
            int mid = (left + right) / 2;
            int midTime = getTime(piles, mid);
            if (midTime <= h) {
                if (mid == 1 || getTime(piles, mid - 1) > h) {
                    return mid;
                }

                right = mid - 1;

            } else {
                left = mid + 1;
            }
        }
        return right;
    }
	//计算狒狒每个小时吃mid根,所花费的时间
    private int getTime(int[] piles, int mid) {
        int time = 0;
        for (int pile : piles) {
            time += pile / mid;
            if (pile % mid != 0) {
                time++;
            }
        }
        return time;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值