497. 非重叠矩形中的随机点

给定一个由非重叠的轴对齐矩形的数组 rects ,其中 rects[i] = [ai, bi, xi, yi] 表示 (ai, bi) 是第 i 个矩形的左下角点,(xi, yi) 是第 i 个矩形的右上角点。设计一个算法来随机挑选一个被某一矩形覆盖的整数点。矩形周长上的点也算做是被矩形覆盖。所有满足要求的点必须等概率被返回。

在给定的矩形覆盖的空间内的任何整数点都有可能被返回。

请注意 ,整数点是具有整数坐标的点。

实现 Solution 类:

Solution(int[][] rects) 用给定的矩形数组 rects 初始化对象。
int[] pick() 返回一个随机的整数点 [u, v] 在给定的矩形所覆盖的空间内。
 

示例 1:

输入: 
["Solution", "pick", "pick", "pick", "pick", "pick"]
[[[[-2, -2, 1, 1], [2, 2, 4, 6]]], [], [], [], [], []]
输出: 
[null, [1, -2], [1, -1], [-1, -2], [-2, -2], [0, 0]]

解释:
Solution solution = new Solution([[-2, -2, 1, 1], [2, 2, 4, 6]]);
solution.pick(); // 返回 [1, -2]
solution.pick(); // 返回 [1, -1]
solution.pick(); // 返回 [-1, -2]
solution.pick(); // 返回 [-2, -2]
solution.pick(); // 返回 [0, 0]
 

提示:

1 <= rects.length <= 100
rects[i].length == 4
-109 <= ai < xi <= 109
-109 <= bi < yi <= 109
xi - ai <= 2000
yi - bi <= 2000
所有的矩形不重叠。
pick 最多被调用 104 次。

解题思路:(1)找出所有矩形包含的点的总个数s,遍历rects数组,对每一个rects[i],其中点的个数是(rects[2]-rects[0])*(rects[3]-rects[1])。遍历的过程中同时记录前i个矩形共包含的点的个数。

(2)产生一个随机数r,范围是0~s-1

(3)找出随机数r指向的点在第几个矩阵中,二分查找法,找到第一个大于随机数的矩阵(r从0开始,相等的时候随机数r指向下一个矩阵的首个点)。

(4)找出r指向的点在该矩阵中的位置,设置点的次序按行排列。

class Solution {
    int s;
    int len;
    int[] si;
    int[][] rects;
    public Solution(int[][] rects) {
        this.rects = rects;
        s = 0;
        int xlen = 0;
        int ylen = 0;
        len = rects.length;
        si = new int[len];
        for(int i = 0; i < len; i++){
            xlen = rects[i][2] - rects[i][0] + 1;
            ylen = rects[i][3] - rects[i][1] + 1;
            s += xlen * ylen;
            si[i] = s;
        }
    }
    
    public int[] pick() {
        Random r = new Random();
        int ran = r.nextInt(s);
        int left = 0;
        int right = len - 1;
        int temp;
        while(left < right){
            int mid = (left + right) / 2;
            if(si[mid] <= ran)
                left = mid + 1;
            else
                right = mid;
        }
        if(left > 0)
            temp = ran - si[left - 1];
        else
            temp = ran;
        int retx = rects[left][0] + temp % (rects[left][2] - rects[left][0] + 1);
        int rety = rects[left][1] + temp / (rects[left][2] - rects[left][0] + 1);
        int[] ret = {retx, rety};
        return ret;
    }
}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Vue实现多个元素随机定位显示且不重叠,可以使用以下步骤: 1. 在Vue组件创建一个数组,用于存储每个元素的位置信息,包括left和top属性。 2. 使用Vue的生命周期函数mounted,在组件挂载后,使用ref获取到需要进行随机定位的区域。 3. 在mounted函数,使用随机数生成器Math.random(),生成每个元素的left和top属性,然后判断当前元素是否与之前的元素重叠,如果重叠则重新生成随机数。 4. 将每个元素的位置信息存储到之前创建的数组。 5. 在模板使用v-for循环遍历数组,渲染出每个元素。 例如,假设我们需要在一个宽为500px,高为500px的区域内随机定位显示10个矩形,可以按照以下代码实现: ```vue <template> <div class="container" ref="container"> <div v-for="(item, index) in items" :key="index" class="box" :style="{left: item.left + 'px', top: item.top + 'px'}"></div> </div> </template> <script> export default { data() { return { items: [] } }, mounted() { const container = this.$refs.container const width = container.offsetWidth const height = container.offsetHeight const count = 10 const size = 50 for (let i = 0; i < count; i++) { let left = Math.floor(Math.random() * (width - size)) let top = Math.floor(Math.random() * (height - size)) while (this.isOverlap(left, top, size)) { left = Math.floor(Math.random() * (width - size)) top = Math.floor(Math.random() * (height - size)) } this.items.push({ left, top }) } }, methods: { isOverlap(left, top, size) { for (let i = 0; i < this.items.length; i++) { const item = this.items[i] if ( left + size > item.left && left < item.left + size && top + size > item.top && top < item.top + size ) { return true } } return false } } } </script> <style> .container { position: relative; width: 500px; height: 500px; border: 1px solid #000; } .box { position: absolute; width: 50px; height: 50px; background-color: #f00; } </style> ``` 在mounted函数,我们使用ref获取到容器元素,然后根据容器的宽度和高度,以及需要显示的元素数量和大小,生成每个元素的left和top属性,并使用isOverlap方法判断是否与之前的元素重叠。最终,将每个元素的位置信息存储到items数组,并在模板使用v-for循环渲染出每个元素。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值