面试题72:
问题:
输入一个非负整数,计算它的平方根。
解决方案:
- 使用二分查找。一个数x的平方根一定小于或等于x,同时,除了0之外的所有非负整数的平方根都大于等于1,故该数的平方根在1到x的范围内。
- 定义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:
问题:
门卫走开H小时,有n堆香蕉,狒狒去吃香蕉,狒狒一个小时只能吃一堆香蕉,狒狒要在门卫回来前将香蕉吃完,问狒狒每个小时至少得吃多少根香蕉。
解决方案:
- 使用二分查找。狒狒吃香蕉的速度的范围在1和数组中的最大值(也就是n堆香蕉的最大值)记为max根。
- 在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;}
}