For example, if the int[] w ={3,14,1,7}, we can make a presum array based on it: int[] presums = {3, 17, 18, 25}

We using Ramdom's nextInt() to generate a random number:

1. if the number is 1, 2 or 3, return 0;

2.if the number is 4~17, return 1;

3.if the number is 18, return 2;

4.if the number is 19~25 return 3.

We need to notice that the nextInt(25)'s range is 0 ~ 24, so we need to add 1 to the ramdom number, to get 1 ~ 25.

And then we use binary search to search out where the ramdon number should belong to: 1, 2, 3 or 4.

Solution 1:

class Solution {
    private int[] sums;
    private Random r=new Random();
    private int sum =0;
    public Solution(int[] w) {
        sums= new int[w.length];
        sums[0]=w[0];
        for(int i=1;i<w.length;i++){
            sums[i]=sums[i-1]+w[i];
        }
        sum = sums[w.length-1];
    }
    
    public int pickIndex() {
        int random =  r.nextInt(sum);
        for(int i=0;i<sums.length;i++){
            if(random<sums[i]){
                return i;
            }
        }
        return -1;
    }
}

 

Solution2:

I have used a typical binary search template to do it, just work hard to remember it, that is:

left = 0;

right = length;

if f(mid) == target return target

if f(mid) > target r=mid

if f(mid) < target l = mid+1

return l or r.

class Solution {
    Random r = new Random();
    int sum =0;
    int[] presums;
    public Solution(int[] w) {
        presums = new int[w.length];
        for(int i=0;i<w.length;i++){
            sum+=w[i];
            presums[i]=sum;
        }
    }
    
    public int pickIndex() {
        int i = r.nextInt(sum)+1;  //the nextInt's range is 0~sum-1, but we need 1~sum
        return binarySearch(i);
        
    }
    
    private int binarySearch(int target){      //this binary search is using a typical template
        int l=0, r=presums.length, mid, res=0;
        while(l<r){
            mid =(l+r)/2;
            if(presums[mid]==target){
                return mid;
            }else if(presums[mid]>target){
                r=mid;
            }else{
                l=mid+1;
            }
        }
        return l;
    }
}

 Solution 3:

Using Universal binary search template

class Solution {
    private int[] sums;
    private Random r=new Random();
    private int sum =0;
    public Solution(int[] w) {
        sums= new int[w.length];
        sums[0]=w[0];
        for(int i=1;i<w.length;i++){
            sums[i]=sums[i-1]+w[i];
        }
        sum = sums[w.length-1];
    }
    
    public int pickIndex() {int random =  r.nextInt(sum);
        int l =0, r = sums.length-1;
        while(l+1<r){
            int mid = (l+r)/2;
             if(random < sums[mid]){
                r=mid;
            }else{
                l=mid;
            }
        }
        if(random < sums[l])
            return l;
        else 
            return r;
    }
}

 

posted on 2022-02-08 13:46  阳光明媚的菲越  阅读(17)  评论(0编辑  收藏  举报