zoukankan      html  css  js  c++  java
  • 497. Random Point in Non-overlapping Rectangles

    Given a list of non-overlapping axis-aligned rectangles rects, write a function pick which randomly and uniformily picks an integer point in the space covered by the rectangles.

    Note:

    1. An integer point is a point that has integer coordinates. 
    2. A point on the perimeter of a rectangle is included in the space covered by the rectangles. 
    3. ith rectangle = rects[i] = [x1,y1,x2,y2], where [x1, y1] are the integer coordinates of the bottom-left corner, and [x2, y2] are the integer coordinates of the top-right corner.
    4. length and width of each rectangle does not exceed 2000.
    5. 1 <= rects.length <= 100
    6. pick return a point as an array of integer coordinates [p_x, p_y]
    7. pick is called at most 10000 times.

    Example 1:

    Input: 
    ["Solution","pick","pick","pick"]
    [[[[1,1,5,5]]],[],[],[]]
    Output: 
    [null,[4,1],[4,1],[3,3]]
    

    Example 2:

    Input: 
    ["Solution","pick","pick","pick","pick","pick"]
    [[[[-2,-2,-1,-1],[1,0,3,0]]],[],[],[],[],[]]
    Output: 
    [null,[-1,-2],[2,0],[-2,-1],[3,0],[-2,-2]]

    Explanation of Input Syntax:

    The input is two lists: the subroutines called and their arguments. Solution's constructor has one argument, the array of rectangles rectspick has no arguments. Arguments are always wrapped with a list, even if there aren't any.

    https://leetcode.com/problems/random-point-in-non-overlapping-rectangles/discuss/316890/Trying-to-explain-why-the-intuitive-solution-wont-work

    以开始想到随机挑选一个rec然后随机选里面的点不就行了?但这样是不行的,因为rec面积不同,但你选他们的概率却是相同的,这样不符合random,因为对大面积的rec不公平。上面的链接解释了这一情况

    class Solution {
        TreeMap<Integer, Integer> 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) };
        }
    }

    正确的方法:

    像presum一样,把presum和对应的数组index存到map中,然后rand.nextInt(sum) + 1代表当前取到的随机sum,然后看他在哪个recindex里,随即返回那个rec里的一个点即可。

    ceilingKey:return a key larger or equal than parameter.

  • 相关阅读:
    Java学习day2
    Java 学习day1
    const
    数组
    scanf、printf、gets、puts的应用及区别
    指针数组和数组指针
    指针函数和函数指针
    nginx Windows版使用说明
    windows平台上nginx部署web.py(转)
    python安装程序是报这样的错UnicodeDecodeError: 'ascii' codec can't decode byte 0xb0 in position 1: ordinal not in range(128)
  • 原文地址:https://www.cnblogs.com/wentiliangkaihua/p/13548095.html
Copyright © 2011-2022 走看看