非重叠矩形中的随机点

简介: 🎈每天进行一道算法题目练习,今天的题目是“非重叠矩形中的随机点”。

说在前面

🎈每天进行一道算法题目练习,今天的题目是“非重叠矩形中的随机点”。

问题描述

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

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

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

实现 Solution 类:

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

示例 1:

image.png

输入:

["Solution","pick","pick","pick","pick","pick"]
[[[[-2,-2,1,1],[2,2,4,6]]],[],[],[],[],[]]

输出:

[null,[-1,-2],[2,0],[-2,-1],[3,0],[-2,-2]

解释:

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
-10^9 <= ai < xi <= 10^9
-10^9 <= bi < yi <= 10^9
xi - ai <= 2000
yi - bi <= 2000
所有的矩形不重叠。
pick 最多被调用 10^4 次。

思路分析

首先我们应该要先理解题目的题意,题目会给我们一个矩形数组,我们需要从矩形数组覆盖的点集合中随机获取一个点,所有满足要求的点必须等概率被返回。\
理解了题目要求后我们也就可以开始思考应该要怎么做了,最简单直接的做法当然是将所有矩形覆盖的点都统计出来,再随机从所有的点中抽取一个就可以了,但是让我们来看看数据量,数据的大小为:

-10^9 <= ai < xi <= 10^9
-10^9 <= bi < yi <= 10^9

这样直接将所有的点统计出来必然会超出时间限制,所以这个做法不行,我们应该要换个思路再想想。我们可以先确定一个矩形,然后在从矩形中随机找一个点吗?当然可以,只要注意下面这一点就可以了:
所有满足要求的点必须等概率被返回。所有的点被返回的概率相等,即矩形中的点数也多(矩形越大),该矩形被选中的概率越大。所以我们应该要先确认矩形被选中的概率,而后等概率抽取出一个矩形,在从矩形中抽取一个点,这样计算出的答案就是满足题意的,所有的点被返回的概率相等

  • 1、计算每个矩形被选中的概率

计算所有矩形覆盖面积的点数num,再统计每个矩形覆盖的点数map[i],则每个矩形被选中的概率为map[i] / num;

rects.map(item=>{
    num += (item[2] - item[0] + 1) * (item[3] - item[1] + 1);
    map.push(num);
});
  • 2、随机选择一个矩形

前面我们确定了所有矩形覆盖面积的点数,以及每个矩形的覆盖点数,所以我们可以从所有点数中随机抽取一个,然后在判断它位于哪个矩形中即可。

const num = this.getRandomNum(1,this.num);
let ind = 0;
while(!((this.map[ind - 1] || 0) <= num && num <= this.map[ind])) ind++;
const rect = this.rects[ind];
  • 3、从矩形中随机选择一个点

确认了选中的矩形之后,我们就可以直接从矩形中随机获取一个点了。

const x = this.getRandomNum(rect[0],rect[2]);
const y = this.getRandomNum(rect[1],rect[3]);
return [x,y];

AC代码

/**
 * @param {number[][]} rects
 */
 var Solution = function(rects) {
    this.rects = rects;
    let num = 0;
    let map = [];
    rects.map(item=>{
        num += (item[2] - item[0] + 1) * (item[3] - item[1] + 1);
        map.push(num);
    });
    this.map = map;
    this.num = num;
};
Solution.prototype.getRandomNum = function(minNum, maxNum) {
    minNum = parseInt(minNum);
    maxNum = parseInt(maxNum);
    const res = Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum;
    return res;
};
Solution.prototype.pick = function() {
    const num = this.getRandomNum(1,this.num);
    let ind = 0;
    while(!((this.map[ind - 1] || 0) <= num && num <= this.map[ind])) ind++;
    const rect = this.rects[ind];
    const x = this.getRandomNum(rect[0],rect[2]);
    const y = this.getRandomNum(rect[1],rect[3]);
    return [x,y];
};

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

说在后面

🎉这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,平时也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。
目录
相关文章
|
Ubuntu 安全 关系型数据库
window下的子系统ubuntu 运行docker遇到的坑
<p>  1.启动mysql容器后,使用docker ps 查看时是没有启动起来 ,使用docker logs 容器id 时,查看报错信息如下:</p> <p>  mysql_ssl_rsa_setup: Can't change permissions of the file 'ca-key.pem' (Errcode: 1 - Operation not permitted)</p> <p>  2021-06-27 11:56:04 [ERROR] Error setting file permissions forca-key.pem and ca.pem</p>
2897 0
|
10月前
|
存储 弹性计算 人工智能
2025年阿里云企业云服务器ECS选购与配置全攻略
本文介绍了阿里云服务器的核心配置选择方法论,涵盖算力需求分析、网络与存储设计、地域部署策略三大维度。针对不同业务场景,如初创企业官网和AI模型训练平台,提供了具体配置方案。同时,详细讲解了购买操作指南及长期运维优化建议,帮助用户快速实现业务上云并确保高效运行。访问阿里云官方资源聚合平台可获取更多最新产品动态和技术支持。
|
SQL druid Java
JDBC和数据库连接池-两个工具类-JDBCUtilsByDruid和BasicDAO
JDBC和数据库连接池-两个工具类-JDBCUtilsByDruid和BasicDAO
547 0
|
12月前
|
存储 安全 网络安全
EV代码签名证书怎么申请?
在数字化时代,EV(Extended Validation)代码签名证书因其严格的验证过程和高信任级别,成为软件开发者确保软件真实性和完整性的重要工具。本文介绍了EV代码签名证书的概述、申请流程、重要性及实际应用价值,强调了其在提升用户信任、软件安全性和品牌形象等方面的作用。PinTrust作为数字证书安全服务商,提供多种类型的证书,是企业和机构值得信赖的合作伙伴。
EV代码签名证书怎么申请?
|
10月前
|
数据可视化 数据挖掘 BI
如何提高做报表的效率?排名前五的报表软件盘点!
如何提高做报表的效率?排名前五的报表软件盘点!
|
Windows
代码签名证书如何申请
代码签名证书如何申请
405 0
|
机器学习/深度学习 搜索推荐 TensorFlow
使用Python实现深度学习模型:智能零售与智能购物
【8月更文挑战第3天】 使用Python实现深度学习模型:智能零售与智能购物
392 2
|
Dart 前端开发 API
Flutter笔记:手写一个简单的画板工具
1. 任务介绍Flutter笔记实现一个简单的画板工具作者目 录1. 任务介绍2. 知识点准备3. 代码实现与效果1. 任务介绍在本文中,我们将一起开发一个基本的Flutter画板应用,用户可以在画板上自由绘制,选择不同的颜色来绘制线条。这个画板应用将允许用户通过点击颜色选择按钮来选择画笔的颜色,并提供鼠标光标支持以增强用户体验。
601 0
|
SQL 关系型数据库 数据库连接
Python连接线上数据库的实战指南
Python连接线上数据库的实战指南
1014 1
|
iOS开发
如何识别手机是否有灵动岛(dynamic island)
如何识别手机是否有灵动岛(dynamic island)
737 0