Dichotomy search summary and best practice

Keywords: REST less

(I) use scenarios

  1. Usually in the ordered numbers, find a number that meets certain conditions
  2. Multiple questions
  3. It needs to be traversed many times and has a large amount of data

(II) basic process

  1. Determine the boundary (low, high) value
  2. To determine the boundary moving condition, write only one side moving (low=mid high=mid-1) or (low=mid+1 high=mid)
  3. 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.


Posted by terrabull on Mon, 09 Dec 2019 08:46:57 -0800