leetcode 850. Rectangle Area II
给定一些矩形2 求覆盖面积 矩形不超过200个
1#
算法1 朴素思想 虽然朴素但是代码却有意思
利用容斥原理
复杂度高达 N*2^N
class Solution:
def intersect(rec1,rec2):
return [max(rec1[1],rec2[1]),
max(rec1[2],rec2[2]),
min(rec1[3],rec2[3]),
min(rec1[4],rec2[4]
]
#这里是两个矩形的两点式求 矩形的相交子矩形 *非常值得思考
def area(rec):
dx=max(0,rec[2]-rec[0])
dy=max(0,rec[3]-rec[1])
return dx*dy
ans=0
for size in range(1,len(rectangles)+1):
for group in itertools.combinations(rectangles,size):
ans = ans +(-1)** (size+1) * area(reduce(intersect,group))
return ans%mod
2#
点位压缩,压缩后进行暴力循环
同时压缩x和y
最后返回
class Solution(object):
def rectangleArea(self, rectangles):
N = len(rectangles)
Xvals, Yvals = set(), set()
for x1, y1, x2, y2 in rectangles:
Xvals.add(x1); Xvals.add(x2)
Yvals.add(y1); Yvals.add(y2)
imapx = sorted(Xvals)
imapy = sorted(Yvals)
mapx = {x: i for i, x in enumerate(imapx)}
mapy = {y: i for i, y in enumerate(imapy)}
grid = [[0] * len(imapy) for _ in imapx]
for x1, y1, x2, y2 in rectangles:
for x in xrange(mapx[x1], mapx[x2]):
for y in xrange(mapy[y1], mapy[y2]):
grid[x][y] = 1
ans = 0
for x, row in enumerate(grid):
for y, val in enumerate(row):
if val:
ans += (imapx[x+1] - imapx[x]) * (imapy[y+1] - imapy[y])
return ans % (10**9 + 7)
N^3
3#
算法3 扫描线算法
将每一个矩形看作一个 "事件" 这样的事件
class Solution(object):
def rectangleArea(self, rectangles):
# Populate events
OPEN, CLOSE = 0, 1
events = []
for x1, y1, x2, y2 in rectangles:
events.append((y1, OPEN, x1, x2))
events.append((y2, CLOSE, x1, x2))
events.sort()
def query():
ans = 0
cur = -1
for x1, x2 in active:
cur = max(cur, x1)
ans += max(0, x2 - cur)
cur = max(cur, x2)
return ans
active = []
cur_y = events[0][0]
ans = 0
for y, typ, x1, x2 in events:
# For all vertical ground covered, update answer
ans += query() * (y - cur_y)
# Update active intervals
if typ is OPEN:
active.append((x1, x2))
active.sort()
else:
active.remove((x1, x2))
cur_y = y
return ans % (10**9 + 7)
4#
注意到刚才的3算法中使用了 区间维护的算法 这里使用线段树维护这个区间
使得达到 NlogN
下面是py 实现线段树
class Node:
def __init__(self,start,end):
self.start=start
self.end=end
self.mid=(start+end)//2
self.active_count=0
self.totle =0
self._left=None
self._right=None
@property
def right(self):
self._right= self._right or Node(self.mid,self.end)
return self._right
@property
def left(self):
self._left=self._left or Node(self.start,self.mid)
return self._left
#更新 i j 合适的区域 + val
#同时返回 i j 之间的x大小
def update(self,i,j,val):
print(str(i)+" "+str(j))
if(i>=j):
return 0
if(i==self.start and j==self.end):
self.active_count = self.active_count + val
else:
self.left .update( i, min( self.mid ,j ) , val )
self.right.update( max(self.mid,i) ,j, val )
#当前区域有 至少一个覆盖
if(self.active_count>0):
self.totle= X[self.end]-X[self.start]
else:
self.totle= self.left.totle + self.right.totle
return self.totle
class Solution:
def rectangleArea(self, rectangles):
"""
:type rectangles: List[List[int]]
:rtype: int
"""
ACTIVE = 1
DEACTIVE = -1
global X
X=set()
events=[]
for rect in rectangles:
X.add(rect[0])
X.add(rect[2])
events.append([rect[1],rect[0],rect[2],ACTIVE])
events.append([rect[3],rect[0],rect[2],DEACTIVE])
X=sorted(X)
events=sorted(events)
pos2idx={ x:i for i,x in enumerate(X) }
sum_area=0
y_cur=0
y_cur_next=0
x_cur=0
SegNode = Node(0,len(pos2idx))
print(pos2idx)
for event in events:
y_cur_next=event[0]
sum_area=sum_area+(y_cur_next-y_cur)*x_cur
x_cur=SegNode.update(pos2idx[event[1]],pos2idx[event[2]],event[3])
print(event)
print(x_cur)
y_cur=y_cur_next
return sum_area%(1000000000 + 7)
注意这里的 下标实际意义不是 容器 而是 标志
所以 会有
start mid
mid end
这样的划分方法 应该注意
另外利用python 的 property 很方便的写出了懒申请策略
(python 做点集压缩真的方便
付:
leetcode 56. Merge Intervals On 求overlap
leetcode 850. Rectangle Area II的更多相关文章
- [LeetCode] 850. Rectangle Area II 矩形面积之二
We are given a list of (axis-aligned) rectangles. Each rectangle[i] = [x1, y1, x2, y2] , where (x1, ...
- [LeetCode] 223. Rectangle Area 矩形面积
Find the total area covered by two rectilinearrectangles in a 2D plane. Each rectangle is defined by ...
- leetcode之Rectangle Area
Find the total area covered by two rectilinear rectangles in a 2D plane. Each rectangle is defined b ...
- [Swift]LeetCode850. 矩形面积 II | Rectangle Area II
We are given a list of (axis-aligned) rectangles. Each rectangle[i] = [x1, y1, x2, y2] , where (x1, ...
- Java for LeetCode 223 Rectangle Area
Find the total area covered by two rectilinear rectangles in a 2D plane. Each rectangle is defined b ...
- (easy)LeetCode 223.Rectangle Area
Find the total area covered by two rectilinear rectangles in a 2D plane. Each rectangle is defined b ...
- leetcode:Rectangle Area
Find the total area covered by two rectilinear rectangles in a 2D plane. Each rectangle is defined b ...
- Java [Leetcode 223]Rectangle Area
题目描述: Find the total area covered by two rectilinear rectangles in a 2D plane. Each rectangle is def ...
- LeetCode(41)-Rectangle Area
题目: Find the total area covered by two rectilinear rectangles in a 2D plane. Each rectangle is defin ...
随机推荐
- ZOJ-1107-FatMouse and Cheese-dfs+记忆化搜索
FatMouse has stored some cheese in a city. The city can be considered as a square grid of dimension ...
- NYOJ 119 士兵杀敌(三)【ST算法】 分类: Brush Mode 2014-11-13 20:56 101人阅读 评论(0) 收藏
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=119 解题思路: RMQ算法. 不会的可以去看看我总结的RMQ算法. http://blo ...
- python元祖,join(),range()
一.元祖定义 元组:俗称不可变的列表,又被成为只读列表,元祖也是python的基本数据类型之一,用小括号括起来,里面可以放任何数据类型的数据,查询可以,循环也可以,切片也可以.但就是不能改. 儿子不能 ...
- 机器学习-反向传播算法(BP)代码实现(matlab)
%% Machine Learning Online Class - Exercise 4 Neural Network Learning % Instructions % ------------ ...
- shell脚本使用需要注意的地方
shell脚本中,函数内部定义变量可以为局部变量和全局变量,局部变量使用local定义,全局变量不带local,全局变量可以在函数外部可见,如下: #!/bin/bash function calle ...
- LoadRunner穿过防火墙运行Vuser和进行监控
LoadRunner穿过防火墙运行Vuser和进行监控 LoadRunner穿过防火墙进行测试,总结下来是2个方法:1. 在controller和Vuser的LAN中的防火墙都打开54345端口即 ...
- 【JZOJ3236】矮人排队
description 在七山七海之外的一个小村庄,白雪公主与N个矮人住在一起,所有时间都花在吃和玩League of Legend游戏.白雪公主决心终结这样的生活,所以为他们举办了体育课. 在每节课 ...
- Django项目在linux上运行
目录 前言 上传 解压 制作启动脚本 这是一篇关于如何在linux下,以后台进程的方式运行服务,命令改改基本上就通用了. 前言 我们在windows本地开发完Django项目后,需要把项目部署到lin ...
- CreateProcess函数详解及示例
WIN32API函数CreateProcess用来创建一个新的进程和它的主线程,这个新进程运行指定的可执行文件. 函数原型: BOOL CreateProcess ( LPCTSTR lpApplic ...
- atoi和itoa函数的实现方法
atoi的实现: #include<iostream> using namespace std; int atio1(char *s) { int sign=1,num=0; if(*s= ...