2022-10-09:我们给出了一个(轴对齐的)二维矩形列表 rectangles 。
对于 rectangle[i] = [x1, y1, x2, y2],其中(x1,y1)是矩形 i 左下角的坐标
(xi1, yi1) 是该矩形 左下角 的坐标, (xi2, yi2) 是该矩形 右上角 的坐标。
计算平面中所有 rectangles 所覆盖的 总面积 。
任何被两个或多个矩形覆盖的区域应只计算 一次 。
返回 总面积 。因为答案可能太大,返回 10^9 + 7 的 模 。
输入:rectangles = [[0,0,2,2],[1,0,2,3],[1,0,3,1]]。
输出:6。

答案2022-10-09:

线段树模板题。一个矩形两个事件。这道题用了树结构,对于rust有点复杂,用了Rc<RefCell>的数据类型。
力扣850上测试,rust语言占用内存最低,go语言占用内存略高于rust,但运行速度最快。
不管怎么说,rust和go都是要优于java的。用java的人们,你们赶紧换语言,java过时了。
java,go,rust运行情况见截图。

代码用rust编写。代码如下:

  1. use std::cell::RefCell;
  2. use std::iter::repeat;
  3. use std::rc::Rc;
  4. impl Solution {
  5. pub fn rectangle_area(rectangles: Vec<Vec<i32>>) -> i32 {
  6. let n = rectangles.len() as i32;
  7. let mut arr: Vec<Vec<i64>> = repeat(repeat(0).take(4).collect())
  8. .take((n << 1) as usize)
  9. .collect();
  10. let mut max: i64 = 0;
  11. for i in 0..n {
  12. // x1 y1 左下角点的坐标
  13. // x2 y2 右上角点的坐标
  14. // 解释一下y1为啥要+1
  15. // 比如y1 = 3, y2 = 7
  16. // 实际的处理的时候,真实的线段认为是闭区间[4,7]的
  17. // 如果不这么处理会有问题
  18. // 比如先在y1 = 3, y2 = 7上,都+1
  19. // 那么此时:
  20. // value: 0 0 1 1 1 1 1 0
  21. // index: 1 2 3 4 5 6 7 8
  22. // 这是不对的!
  23. // 因为线段[3,7]长度是4啊!而在线段树里,是5个1!
  24. // 所以,y1 = 3, y2 = 7
  25. // 我们就是认为是4~7,都+1
  26. // 那么此时:
  27. // value: 0 0 0 1 1 1 1 0
  28. // index: 1 2 3 4 5 6 7 8
  29. // 线段树上,正好4个1,和我们想要的距离是一致的
  30. let x1 = rectangles[i as usize][0];
  31. let y1 = rectangles[i as usize][1] + 1;
  32. let x2 = rectangles[i as usize][2];
  33. let y2 = rectangles[i as usize][3];
  34. arr[i as usize][0] = x1 as i64;
  35. arr[i as usize][1] = y1 as i64;
  36. arr[i as usize][2] = y2 as i64;
  37. arr[i as usize][3] = 1;
  38. arr[(i + n) as usize][0] = x2 as i64;
  39. arr[(i + n) as usize][1] = y1 as i64;
  40. arr[(i + n) as usize][2] = y2 as i64;
  41. arr[(i + n) as usize][3] = -1;
  42. max = get_max(max, y2 as i64);
  43. }
  44. return cover_area(&mut arr, n << 1, max);
  45. }
  46. }
  47. fn get_max<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
  48. if a > b {
  49. a
  50. } else {
  51. b
  52. }
  53. }
  54. fn cover_area(arr: &mut Vec<Vec<i64>>, n: i32, max: i64) -> i32 {
  55. // 所有的事件,都在arr里
  56. // [x, y1, y2, +1/-1]
  57. // 早 -> 晚
  58. //Arrays.sort(arr, 0, n, (a, b) -> a[0] <= b[0] ? -1 : 1);
  59. arr[0..n as usize].sort_by(|a, b| {
  60. if a[0] < b[0] {
  61. std::cmp::Ordering::Less
  62. } else {
  63. std::cmp::Ordering::Greater
  64. }
  65. });
  66. // max y的值,可能的最大值,非常大也支持!
  67. let mut dst = DynamicSegmentTree::new(max);
  68. let mut pre_x: i64 = 0;
  69. let mut ans: i64 = 0;
  70. for i in 0..n {
  71. // dst.query() : 开点线段树告诉你!y方向真实的长度!
  72. ans += dst.query() * (arr[i as usize][0] - pre_x);
  73. ans %= 1000000007;
  74. pre_x = arr[i as usize][0];
  75. dst.add(arr[i as usize][1], arr[i as usize][2], arr[i as usize][3]);
  76. }
  77. return ans as i32;
  78. }
  79. struct Node {
  80. cover: i64,
  81. len: i64,
  82. left: Option<Rc<RefCell<Node>>>,
  83. right: Option<Rc<RefCell<Node>>>,
  84. }
  85. impl Node {
  86. fn new() -> Self {
  87. Self {
  88. cover: 0,
  89. len: 0,
  90. left: Option::None,
  91. right: Option::None,
  92. }
  93. }
  94. }
  95. struct DynamicSegmentTree {
  96. root: Rc<RefCell<Node>>,
  97. size: i64,
  98. }
  99. impl DynamicSegmentTree {
  100. fn new(max: i64) -> Self {
  101. Self {
  102. root: Rc::new(RefCell::new(Node::new())),
  103. size: max,
  104. }
  105. }
  106. pub fn add(&mut self, ll: i64, rr: i64, cover: i64) {
  107. self.add0(Rc::clone(&self.root), 1, self.size, ll, rr, cover);
  108. }
  109. fn add0(&mut self, cur: Rc<RefCell<Node>>, l: i64, r: i64, ll: i64, rr: i64, cover: i64) {
  110. if ll <= l && rr >= r {
  111. cur.as_ref().borrow_mut().cover += cover;
  112. } else {
  113. if cur.as_ref().borrow().left.is_none() {
  114. cur.as_ref().borrow_mut().left = Some(Rc::new(RefCell::new(Node::new())));
  115. }
  116. if cur.as_ref().borrow().right.is_none() {
  117. cur.as_ref().borrow_mut().right = Some(Rc::new(RefCell::new(Node::new())));
  118. }
  119. let m: i64 = l + ((r - l) >> 1);
  120. if ll <= m {
  121. self.add0(
  122. Rc::clone(&cur.as_ref().borrow().left.as_ref().unwrap()),
  123. l,
  124. m,
  125. ll,
  126. rr,
  127. cover,
  128. );
  129. }
  130. if rr > m {
  131. self.add0(
  132. Rc::clone(&cur.as_ref().borrow().right.as_ref().unwrap()),
  133. m + 1,
  134. r,
  135. ll,
  136. rr,
  137. cover,
  138. );
  139. }
  140. }
  141. self.push_up(cur, l, r);
  142. }
  143. fn push_up(&mut self, cur: Rc<RefCell<Node>>, l: i64, r: i64) {
  144. if cur.as_ref().borrow().cover > 0 {
  145. cur.as_ref().borrow_mut().len = r - l + 1;
  146. } else {
  147. cur.as_ref().borrow_mut().len = if !cur.as_ref().borrow().left.is_none() {
  148. cur.as_ref()
  149. .borrow_mut()
  150. .left
  151. .as_mut()
  152. .unwrap()
  153. .as_ref()
  154. .borrow()
  155. .len
  156. } else {
  157. 0
  158. } + if !cur.as_ref().borrow().right.is_none() {
  159. cur.as_ref()
  160. .borrow_mut()
  161. .right
  162. .as_mut()
  163. .unwrap()
  164. .as_ref()
  165. .borrow()
  166. .len
  167. } else {
  168. 0
  169. };
  170. }
  171. }
  172. pub fn query(&mut self) -> i64 {
  173. return self.root.as_ref().borrow().len;
  174. }
  175. }
  176. fn main() {
  177. let rectangles = vec![vec![0, 0, 2, 2], vec![1, 0, 2, 3], vec![1, 0, 3, 1]];
  178. let ans = Solution::rectangle_area(rectangles);
  179. println!("ans = {:?}", ans);
  180. }
  181. struct Solution {}

执行结果如下:



左神java代码

2022-10-09:我们给出了一个(轴对齐的)二维矩形列表 rectangles 。 对于 rectangle[i] = [x1, y1, x2, y2],其中(x1,y1)是矩形 i 左下角的坐的更多相关文章

  1. 用Python+qrcode库创建一个包含信息的二维码

    安装qrcode库和PIL库 在命令行中分别输入pip install qrcode 和pip install pillow 导入库格式如下: import PIL import qrcode 下面以 ...

  2. 一个不错的PHP二维数组排序函数简单易用存用

    一个不错的PHP二维数组排序函数简单易用存用 传入数组,传入排序的键,传入排序顺序 public function array_sort($arr,$keys,$type='asc') { $keys ...

  3. 旋转图像 给定一个 n × n 的二维矩阵表示一个图像。

    给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: 你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵.请不要使用另一个矩阵来旋转图像. 示例 : 给定 ma ...

  4. 小程序踩过的一个小坑---解析二维码decodeURIComponent() url解码

    因为我们需要用户扫码进入小程序,每一个货柜都有一个对应的二维码,当然每个二维码里的信息也不一样.用户扫码进入小程序之后,二维码的信息会以参数q带进去,而我们只能在onLoad事件中拿到这个参数, 但是 ...

  5. Anaconda+django写出第一个web app(二)

    今天开始建立App中的第一个Model,命名为Tutorial. Model的定义在main文件夹下的models.py中通过类进行,我们希望Tutorial这个model包含三个属性:标题.内容和发 ...

  6. 存在一个足够大的二维数组,每个数组中的值都是整数,使用javascript如何实现按每个数组中的平均值,从大到小排序这个二维数组?

    这是牛客网上的一道题~ 题意:对数组排序,顺序是按照数组的平均值,即按照一个元素和平均值相减的绝对值的大小来排序...本例按这个绝对值递增排序 解题思想:先求出这个数组的平均值,如果 a<b,那 ...

  7. 一个for循环打印二维数组

    #include<stdio.h> #define MAXX 2 #define MAXY 3 void printarray() { ,,,,,}; ;i< MAXX*MAXY;i ...

  8. 一个有用的排序函数,array_multisort(),下面的一个用法是根据二维数组里的一个字段值的大小,对该二维数组进行重新排序

    从二维数组$cashes中取出一列 'store_id'(二维数组中的每个一维数组都有的字段),按照这个的大小排序,对二维数组$caches里面的一维数组进行重新排序 实际应用如下 想让相同部门的排在 ...

  9. poj2155一个二维树状数组

                                                                                                         ...

  10. 我写的一个Qt 显示二维码( QR Code)的控件(可以去掉对 libpthread 的依赖,而且编译出的库文件可以在 vc2010 的release 模式下使用)

    最近一个项目需要显示二维码,所以花了点时间(只用了一个晚上,写的很不完善),写了个显示二维码的控件.当然这个控件用到了些开源的代码,比如qrencode,所以我也打算把我的代码开源. 我的代码参考了 ...

随机推荐

  1. Go_day07

    Go常用包 包的本质:创建不同的文件夹,来存放程序文件 Go语言的源码复用建立再包package基础之上 main包 Go语言的入口 main()函数所在的包必须是main包 main包需要引用代码, ...

  2. SQL作业编辑报错 无法将COM组件......

    在命令行运行下列命令 数据库为2005cd C:\Program Files\Microsoft SQL Server\90\DTS\Binnregsvr32 dts.dll

  3. 声网 X 在线自习室 同学陪伴、老师监督的在线自习是如何火出圈的?

    实时互联网像触角一样,通过情景的共享延伸开来,链接着我们彼此的线下.线上生活,形成一张不可分割的网络.随着社交直播.在线教育.视频会议成为大众生活不可或缺的一部分的同时,智能手表.智能作业灯.视频双录 ...

  4. java循环结构中局部变量和成员变量

    前言 在前两篇文章中,壹哥给大家讲解了Java里的条件分支,包括if和switch两种情况.我们知道,除了条件分支结构,还有循环结构,所以接下来的一个学习重点就是Java里的循环.但在学习循环之前,我 ...

  5. 协程 + epoll 的两个小例子

    getcontext/setupcontext/swapcontext/setcontext 方式的协程实现 #include <stdio.h> #include <stdlib. ...

  6. 【ASP.NET Core】在node.js上托管Blazor WebAssembly应用

    由于 Blazor-WebAssembly 是在浏览器中运行的,通常不需要执行服务器代码,只要有个"窝"能托管并提供相关文件的下载即可.所以,当你有一个现成的 Blazor was ...

  7. 【LeetCode动态规划#02】图解不同路径I + II(首次涉及二维dp数组,)

    不同路径 力扣题目链接(opens new window) 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 "Start" ). 机器人每次只能向下或者向右移 ...

  8. WebDriver API及对象识别技术

    html页面的iframe的切换: iframe框架在html页面:实际就是多个html页面的相互嵌套:如果存在多个,则操作对象一直停留在主文档页面:    如果需要操作子文档页面则需要实现ifram ...

  9. C#泛型的逆变协变(个人理解)

    前编 一般来说, 泛型的作用就类似一个占位符, 或者说是一个参数, 可以让我们把类型像参数一样进行传递, 尽可能地复用代码 我有个朋友, 在使用的过程中发现一个问题 IFace<object&g ...

  10. [Linux]Linux中安装软件的方式?

    近日处理安全漏洞时,出现了这样一个问题: 判断某软件组件是通过何种方式安装的. 知道是何种方式安装,才方便做进一步的解决(升级/配置/卸载等操作) 1 解压即用 例如: sublime_text.py ...