zoukankan      html  css  js  c++  java
  • leetcode497

    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]]
     
     
    1.trivial solution. 一开始建立好所有可能的点,然后用O(1) pick其中一个点。 但不现实,如果给的一个长方形面积特别大,那你一开始建立所有点用的memory就爆炸了。
    2.先根据面积作为权重,按概率选到长方形。之后在这个长方形的范围内随机选x和y,输出。
     
    本题相关:Random Pick with Weight:  https://www.cnblogs.com/jasminemzy/p/9741839.html
     
    实现:
    class Solution {
        
        private int[][] rects;
        private Random rd;
        private int[] sum;
        private int total;
        
        public Solution(int[][] rects) {
            this.rects = rects;
            this.rd = new Random();
            int[] weight = new int[rects.length];
            for (int i = 0; i < rects.length; i++) {
                weight[i] = (rects[i][2] - rects[i][0] + 1) * (rects[i][3] - rects[i][1] + 1);
            }
            this.sum = new int[weight.length];
            this.total = 0;
            for (int i = 0; i < sum.length; i++) {
                total += weight[i];
                sum[i] = total;
            }
        }
        
        public int[] pick() {
            int[] rect = rects[pickRect()];
            int x = rect[0] + rd.nextInt(rect[2] - rect[0] + 1);
            int y = rect[1] + rd.nextInt(rect[3] - rect[1] + 1);
            return new int[] {x, y};
        }
        
        private int pickRect() {
            int target = rd.nextInt(total);
            int i = 0, j = sum.length - 1;
            while (i < j) {
                int mid = (i + j) / 2;
                if (sum[mid] > target) {
                    j = mid;
                } else {
                    i = mid + 1;
                }
            }
            return i;
        }
    }
    
    /**
     * Your Solution object will be instantiated and called as such:
     * Solution obj = new Solution(rects);
     * int[] param_1 = obj.pick();
     */
  • 相关阅读:
    Linux学习——操作文件与目录
    链表去重
    Android主题换肤 无缝切换
    android 换肤模式总结
    NotificationListenerService不能监听到通知
    判断app是否在后台
    模拟接听电话的方法,兼容华为android5.0以上设备
    Windows下安装破解JIRA6.3.6
    一些as的配置
    Android BLE开发——Android手机与BLE终端通信初识
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/9741842.html
Copyright © 2011-2022 走看看