LeetCode随机数据结构

470. Implement Rand10() Using Rand7()
解法一:
这个问题腾讯二面问的,我竟然一点思路没有,说实话没刷过类似题目真的很难想到。

/**
 * The rand7() API is already defined in the parent class SolBase.
 * public int rand7();
 * @return a random integer in the range 1 to 7
 */
class Solution extends SolBase {
    public int rand10() {
        int idx=40;
        while(idx>=40)
        {
            int a=rand7();
            int b=rand7();
            idx=(a-1)*7+b-1;
        }
        return 1+idx%10;
        
    }
}

解法二:

/**
 * The rand7() API is already defined in the parent class SolBase.
 * public int rand7();
 * @return a random integer in the range 1 to 7
 */
class Solution extends SolBase {
    public int rand10() {
        int idx;
        while(true)
        {
            int a=rand7();
            int b=rand7();
            idx=(a-1)*7+b;
            
            if(idx<=40)
                return 1+(idx-1)%10;
            //distribute 
            a=idx-40;
            b=rand7();
            idx=(a-1)*7+b;
            if(idx<=60)
                return 1+(idx-1)%10;
            a=idx-60;
            b=rand7();
            idx=(a-1)*7+b;
            if(idx<=20)
                return 1+(idx-1)%10;
        }
    }
}

519. Random Flip Matrix

class Solution {
    
    public HashSet<Integer> set;
    public int n_row;
    public int n_col;

    public Solution(int n_rows, int n_cols) {
        set=new HashSet<>();
        n_row=n_rows;
        n_col=n_cols;
    }
    /*
    3 4
    0 1 2 3
    4 5 6 7
    8 9 10 11
    */
    
    public int[] flip() {
        int[] ret=new int[2];
        if(n_col==0 || n_row==0)
            return ret;
        int rand;
        while(true)
        {
            rand=(int)(Math.random()*(double)this.n_row*this.n_col);
            if(!set.contains(rand))
                break;
        }
        ret[0]=rand/n_col;
        ret[1]=rand%n_col;
        set.add(rand);
        return ret;
    }
    
    public void reset() {
        
        this.set=new HashSet<>();
        
    }
}

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(n_rows, n_cols);
 * int[] param_1 = obj.flip();
 * obj.reset();
 */

528. Random Pick with Weight

class Solution {

    public int[] right;
    public int sum;
    
    public Solution(int[] w) {
        
        sum=0;
        right=new int[w.length];
        for(int i=0;i<w.length;i++)
        {
            sum+=w[i];
            right[i]=sum;
        }
    }
    
    public int pickIndex() {
        double target=Math.random()*sum;
        int i=0;
        for(;i<right.length;i++)
        {
            if(target<=right[i])
                break;
        }
        return i;
    }
    
}

497. Random Point in Non-overlapping Rectangles
因为要返回被矩形区域覆盖的整数坐标点,累计计算的不是矩形的面积,而应该是点的数量(包括矩形边上的点),另外生成的随机数范围因该注意

class Solution {

    public int[] areas;
    public int[][] rects;
    public Solution(int[][] rects) {
        this.areas=new int[rects.length];
        this.rects=rects;
        for(int i=0;i<rects.length;i++)
        {
            int[] rect=rects[i];
            areas[i]=(rect[2]-rect[0]+1)*(rect[3]-rect[1]+1);
        }
        for(int i=1;i<areas.length;i++)
            areas[i]+=areas[i-1];
    }
    
    public int[] pick() {
        int target=(int)(Math.random()*(this.areas[this.rects.length-1]+1));
        int[] ret=new int[2];
        if(rects.length==0)
            return ret;
        int i=0;
        for(;i<this.rects.length;i++)
        {
            if(target<=this.areas[i])
                break;
        }
        
        int[] rect=this.rects[i];
        
        ret[0]=rect[0]+(int)(Math.random()*(rect[2]-rect[0]+1));
        ret[1]=rect[1]+(int)(Math.random()*(rect[3]-rect[1]+1));
        return ret;
    }
}

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(rects);
 * int[] param_1 = obj.pick();
 */

解法二:
基本思路一样,但是在搜索步骤采用了TreeMap来降低查询时间复杂度,当然也可以使用二分法。

class Solution {
    TreeMap<Integer, Integer> map;   //将累积点数(key)与矩形的索引(value)存储在map中
    int[][] arrays;
    int sum;
    Random rnd= new Random();
    
    public Solution(int[][] rects) {
        arrays = rects;
        map = new TreeMap<>();
        sum = 0;
        
        for(int i = 0; i < rects.length; i++) {
            int[] rect = rects[i];
						
            // the right part means the number of points can be picked in this rectangle
            sum += (rect[2] - rect[0] + 1) * (rect[3] - rect[1] + 1);
			
            map.put(sum, i);
        }
    }
    
    public int[] pick() {
        // nextInt(sum) returns a num in [0, sum -1]. After added by 1, it becomes [1, sum]
        int c = map.ceilingKey( rnd.nextInt(sum) + 1);
        
        return pickInRect(arrays[map.get(c)]);
    }
    
    private int[] pickInRect(int[] rect) {
        int left = rect[0], right = rect[2], bot = rect[1], top = rect[3];
        
        return new int[]{left + rnd.nextInt(right - left + 1), bot + rnd.nextInt(top - bot + 1) };
    }
}

478. Generate Random Point in a Circle
采用reject sampling算法

class Solution {

    public double x;
    public double y;
    public double r;
    
    public Solution(double radius, double x_center, double y_center) {
        
        x=x_center;
        y=y_center;
        r=radius;
    }
    
    public double[] randPoint() {
        double dx,dy;
        do{
            dx=(2*Math.random()-1)*this.r;
            dy=(2*Math.random()-1)*this.r;
        }while(dx*dx+dy*dy>r*r);
        double[] ret=new double[2];
        ret[0]=x+dx;
        ret[1]=y+dy;
        return ret;
    }
}

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(radius, x_center, y_center);
 * double[] param_1 = obj.randPoint();
 */

极坐标法:

class Solution {

    public double x;
    public double y;
    public double r;
    
    public Solution(double radius, double x_center, double y_center) {
        
        x=x_center;
        y=y_center;
        r=radius;
    }
    
    public double[] randPoint() {
        
        double angle=Math.random()*360;
        double radius=Math.sqrt(Math.random())*this.r;
        double dx=radius*Math.cos(angle*Math.PI/180);
        double dy=radius*Math.sin(angle*Math.PI/180);
        double[] ret=new double[2];
        ret[0]=x+dx;
        ret[1]=y+dy;
        return ret;
    }
}

猜你喜欢

转载自blog.csdn.net/To_be_to_thought/article/details/89648530