Leetcode 850. 矩形面积 II

2024-03-05 17:30
文章标签 leetcode ii 面积 矩形 850

本文主要是介绍Leetcode 850. 矩形面积 II,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.题目描述

我们给出了一个(轴对齐的)二维矩形列表 rectangles 。 对于 rectangle[i] = [x1, y1, x2, y2],其中(x1,y1)是矩形 i 左下角的坐标,$ (x_{i1}, y_{i1})$ 是该矩形 左下角 的坐标,$ (x_{i2}, y_{i2}) $是该矩形 右上角 的坐标。

计算平面中所有 rectangles 所覆盖的 总面积 。任何被两个或多个矩形覆盖的区域应只计算 一次

返回 总面积 。因为答案可能太大,返回 1 0 9 + 7 10^9 + 7 109+7

在这里插入图片描述


输入:rectangles = [[0,0,2,2],[1,0,2,3],[1,0,3,1]]
输出:6
解释:如图所示,三个矩形覆盖了总面积为6的区域。
从(1,1)到(2,2),绿色矩形和红色矩形重叠。
从(1,0)到(2,3),三个矩形都重叠。


输入:rectangles = [[0,0,1000000000,1000000000]]
输出:49
解释:答案是 1 0 18 10^{18} 1018 ( 1 0 9 + 7 ) (10^9 + 7) (109+7) 取模的结果, 即 49 。


提示:

  • 1 <= rectangles.length <= 200
  • rectanges[i].length = 4
  • 0 < = x i 1 , y i 1 , x i 2 , y i 2 < = 1 0 9 0 <= x_{i1}, y_{i1}, x_{i2}, y_{i2} <= 10^9 0<=xi1,yi1,xi2,yi2<=109
  • 矩形叠加覆盖后的总面积不会超越 2 63 − 1 2^{63} - 1 2631 ,这意味着可以用一个 64 位有符号整数来保存面积结果。

2.思路分析

离散化+扫描线+线段树

Q1: 什么是扫描线?

扫描线就是用来解决矩形覆盖面积问题。

假如想要计算下图的覆盖面积,需要计算两个矩形的面积相加,然后减去中间蓝色交叉的部分。

在这里插入图片描述

若有n个矩形,需要计算n个矩形的面积相加计算,然后减去两两交叉的面积,时间复杂度非常高。

假如可以对其进行分割,如图:

在这里插入图片描述

只需要计算矩形①②③的面积即可,于是问题转化为如何计算矩形①②③的面积。

矩形的宽的计算,只需要把x轴的点按照从小到大的顺序排列即可。

难点是计算矩形的高。于是便有了扫描线。

定义:从左向右看,定义矩形的左侧边为入边,右侧边为出边,也就是扫描的方向,看起来就像用一个线从左向右来扫描所有的矩形

从左往右扫,遇到入边的线,则对入边区间进行+1操作,遇到出边的线,那么对出边区间进行-1操作。然后我们遍历整个区间,就得到了矩形的高。

在这里插入图片描述

  • 当扫描到第一条边,是入边,范围是[1,3],于是给[1,3] + 1,此时整个范围只有[1,3]被覆盖,高为2,第一个矩形面积为 1 * 2 = 2

在这里插入图片描述

  • 当扫描到第二条边,是入边,范围是[2,4],于是给[2,4] + 1,此时整个范围只有[1,4]被覆盖,高为3,第一个矩形面积为 1 * 3 = 3

在这里插入图片描述

  • 当扫描到第三条边,是出边,范围是[1,3],于是给[1,3] - 1,此时整个范围只有[2,4]被覆盖,高为2,第一个矩形面积为 3 * 2 = 6

在这里插入图片描述

  • 当扫描到第四条边,是出边,范围是[2,4],于是我们给[2,4] - 1,此时整个范围没有覆盖,结束计算

]

于是覆盖面积为2 + 3 + 6 = 11

3.代码实现

class Solution:def rectangleArea(self, rectangles: List[List[int]]) -> int:hbound = set()for rect in rectangles:# 下边界hbound.add(rect[1])# 上边界hbound.add(rect[3])hbound = sorted(hbound)m = len(hbound)# 「思路与算法部分」的 length 数组并不需要显式地存储下来# length[i] 可以通过 hbound[i+1] - hbound[i] 得到seg = [0] * (m - 1)sweep = list()for i, rect in enumerate(rectangles):# 左边界sweep.append((rect[0], i, 1))# 右边界sweep.append((rect[2], i, -1))sweep.sort()ans = i = 0while i < len(sweep):j = iwhile j + 1 < len(sweep) and sweep[i][0] == sweep[j + 1][0]:j += 1if j + 1 == len(sweep):break# 一次性地处理掉一批横坐标相同的左右边界for k in range(i, j + 1):_, idx, diff = sweep[k]left, right = rectangles[idx][1], rectangles[idx][3]for x in range(m - 1):if left <= hbound[x] and hbound[x + 1] <= right:seg[x] += diffcover = 0for k in range(m - 1):if seg[k] > 0:cover += (hbound[k + 1] - hbound[k])ans += cover * (sweep[j + 1][0] - sweep[j][0])i = j + 1return ans % (10**9 + 7)

复杂度分析:

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2), 其中 n 是矩形的个数。
  • 空间复杂度: O ( n ) O(n) O(n) ,即为扫描线需要使用的空间 。

参考:

1.https://leetcode.cn/problems/rectangle-area-ii/solution/by-capital-worker-7efv/

2.https://leetcode.cn/problems/rectangle-area-ii/solution/ju-xing-mian-ji-ii-by-leetcode-solution-ulqz/

这篇关于Leetcode 850. 矩形面积 II的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/777270

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

从0到1,AI我来了- (7)AI应用-ComfyUI-II(进阶)

上篇comfyUI 入门 ,了解了TA是个啥,这篇,我们通过ComfyUI 及其相关Lora 模型,生成一些更惊艳的图片。这篇主要了解这些内容:         1、哪里获取模型?         2、实践如何画一个美女?         3、附录:               1)相关SD(稳定扩散模型的组成部分)               2)模型放置目录(重要)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

【JavaScript】LeetCode:16-20

文章目录 16 无重复字符的最长字串17 找到字符串中所有字母异位词18 和为K的子数组19 滑动窗口最大值20 最小覆盖字串 16 无重复字符的最长字串 滑动窗口 + 哈希表这里用哈希集合Set()实现。左指针i,右指针j,从头遍历数组,若j指针指向的元素不在set中,则加入该元素,否则更新结果res,删除集合中i指针指向的元素,进入下一轮循环。 /*** @param

学习记录:js算法(二十八):删除排序链表中的重复元素、删除排序链表中的重复元素II

文章目录 删除排序链表中的重复元素我的思路解法一:循环解法二:递归 网上思路 删除排序链表中的重复元素 II我的思路网上思路 总结 删除排序链表中的重复元素 给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 图一 图二 示例 1:(图一)输入:head = [1,1,2]输出:[1,2]示例 2:(图