解法
要说难其实也不难…… O ( n 2 ) O(n^2) O(n2)的方法都可以过
解法一:暴力
每放下一个方块,记录一下放下后这个方块顶端高度,它由两部分组成:一是方块自己的高度,二是以前放下的与该方块相交的方块的顶端高度的最大值,由这两部分相加构成
得到每个方块放下时的顶端高度之后,最后的ans
数组就是这个高度数组的前缀最大值数组
class Solution(object):
def fallingSquares(self, positions):
"""
:type positions: List[List[int]]
:rtype: List[int]
"""
n = len(positions)
ans = [None]*n
for i in xrange(n):
a,b = positions[i]
ans[i] = b
for j in xrange(i):
c,d = positions[j]
if max(a,c)<min(a+b,c+d):
ans[i] = max(ans[i],ans[j]+b)
for i,a in enumerate(ans[1:]):
ans[i+1] = max(ans[i],a)
return ans
虽然慢,但是比较简单
解法二:离散化
其实这个问题又可以转变成求某区间最大值,以及更新某区间值的一个问题
而这样的问题只和区间端点有关
从题目条件看出,区间只有1000个,那不同的端点数值不会超过2000个
离散化之后再用上面的暴力就可以了
class Solution(object):
def fallingSquares(self, positions):
"""
:type positions: List[List[int]]
:rtype: List[int]
"""
values = sorted({x[0] for x in positions}|{x[0]+x[1]-1 for x in positions})
n = len(values)
idx = {}
for i,c in enumerate(values):
idx[c] = i
heights = [0]*n
ans = []
def query(l,r):
res = 0
for i in xrange(idx[l],idx[r]+1):
res = max(res,heights[i])
return res
def update(l,r,v):
for i in xrange(idx[l],idx[r]+1):
heights[i] = max(heights[i],v)
for i,(x,y) in enumerate(positions):
h = query(x,x+y-1)
update(x,x+y-1,h+y)
if i==0:
ans.append(h+y)
else:
ans.append(max(h+y,ans[-1]))
return ans
线段树+离散化
上面的更新和查询操作其实完全就是线段树的设计,可以用线段树来实现
class ST(object):
def __init__(self,n,uf,qf):
self.n = n
self.uf = uf
self.qf = qf
self.t = [0]*(n<<1)
self.lazy = [0]*n
def _apply(self,x,v):
self.t[x] = self.uf(self.t[x],v)
if x<self.n:
self.lazy[x] = self.uf(self.lazy[x],v)
def _pull(self,x):
while x>1:
x /= 2
self.t[x] = self.qf(self.t[x<<1],self.t[(x<<1)+1])
self.t[x] = self.uf(self.t[x],self.lazy[x])
def update(self,l,r,v):
l += self.n
r += self.n
l0,r0 = l,r
while l<=r:
if l&1:
self._apply(l,v)
l += 1
if not r&1:
self._apply(r,v)
r -= 1
l,r = l>>1,r>>1
self._pull(l0)
self._pull(r0)
def _push(self,x):
H = self.n.bit_length()
for h in xrange(H,0,-1):
y = x>>h
if self.lazy[y]:
self._apply(y<<1,self.lazy[y])
self._apply((y<<1)+1,self.lazy[y])
self.lazy[y] = 0
def query(self,l,r):
l += self.n
r += self.n
self._push(l)
self._push(r)
res = 0
while l<=r:
if l&1:
res = self.qf(res,self.t[l])
l += 1
if not r&1:
res = self.qf(res,self.t[r])
r -= 1
l,r = l>>1,r>>1
return res
class Solution(object):
def fallingSquares(self, positions):
"""
:type positions: List[List[int]]
:rtype: List[int]
"""
values = sorted({x[0] for x in positions}|{x[0]+x[1]-1 for x in positions})
n = len(values)
idx = {}
for i,c in enumerate(values):
idx[c] = i
t = ST(n,max,max)
ans = []
for x,y in positions:
# print idx[x],idx[x+y-1]
v = t.query(idx[x],idx[x+y-1])
t.update(idx[x],idx[x+y-1],y+v)
if ans:
ans.append(max(ans[-1],v+y))
else:
ans.append(v+y)
return ans