(I) use scenarios
- Usually in the ordered numbers, find a number that meets certain conditions
- Multiple questions
- It needs to be traversed many times and has a large amount of data
(II) basic process
- Determine the boundary (low, high) value
- To determine the boundary moving condition, write only one side moving (low=mid high=mid-1) or (low=mid+1 high=mid)
- Out of loop return results (highlight)
(3) simple examples
Given an ordered array of nums and an integer target, can we determine whether the target exists in nums?
public boolean binary_search(int[] nums , int target) { int low = 0; int high = nums.length-1; while(low<high){ int mid = low + (high-low)/2; //Standard writing method, avoid int addition out of bounds if(nums[mid]>target) low = mid+1; else if(nums[mid]<target]) high = mid; } return nums[low]==target; //Out of loop return results }
(IV) selected examples
(1)Leetcode 875 KoKo Eating Bananas
Koko likes to eat bananas. There are N plates of bananas on each plate. There are piles[i] bananas on each plate. There are a total of H hours for Koko to eat
Koko can eat K bananas an hour, but can only choose to eat a plate of bananas in the same hour.
Calculate the minimum K value so that koko can eat all bananas in H hours.
Input: Pipes = [3, 6, 7, 8], H = 8
Output: K = 4
public class Eating_Bananas_875 { public int minEatingSpeed(int[] piles, int H) { int low = 1 , high = piles[0]; for(int i=1;i<piles.length;i++){ if(piles[i]>high) high = piles[i]; } while(low<high){ int mid = low + (high-low)/2; if(check(piles,mid,H)) high = mid; else low = mid+1; } return low;//Out of loop return } public boolean check(int[] piles , int speed,int H){ //The best solution is when low and high meet int time = 0; for(int i=0;i<piles.length;i++){ if(piles[i]%speed==0) time+=piles[i]/speed; //You can't eat another dish for the rest of the time else time += piles[i]/speed+1; } return time<=H; } }
(2) Leetcode 878 Nth Magical Number
Defining an integer is magical if and only if it can be divided by A or B
Given A,B, return the nth magic number, the answer may be very large, it needs mod 10^9+7
1<=N<=10^9, 2<=A,B<=40000
Input: N = 4, A = 2, B = 3
Output: 6
Interpretation: 2,3,4,6
public class Nth_Magical_Number_878 { public int nthMagicalNumber(int N, int A, int B) { long low=2L,high=100000000000000L; //What is the upper bound? Try to find a maximum while(low<high){ long mid = low + (high-low)/2; if(check(mid,N,A,B)) low = mid+1; else high = mid; } return (int)(low%1000000007); //Less parenthesis leads to WA } public boolean check(long mid,int N,int A,int B){ long magicals = mid/A + mid/B - mid/lcm(A,B); return magicals<N ; } public int gcd(int a,int b){ //greatest common divisor return b==0?a:gcd(b,a%b); } public int lcm(int a,int b){ //Minimum common multiple return a*b/gcd(a,b); } }
(III) Leetcode 778 Swim in Rising Water
Given a NxN grid, please find a path from (0,0) to (n-1,n-1) to minimize the maximum value of this path. And return this value.