记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
42.trapping-rain-water 接雨水
解题思路:
保留左右两边的值 中间的按照最高点灌满
假设让水从左侧流出 如果左侧的比本地的要小l[i]>l[i-1] 则水减少至左侧或者本地的柱子高度max(height[i],l[i-1])
从左到右检查一遍后 从右到左在检查一遍
def trap(height):
"""
:type height: List[int]
:rtype: int
[0,1,0,2,1,0,1,3,2,1,2,1]
"""
m = max(height)
if len(height)<3:
return 0
l = [height[0]]+[m]*(len(height)-2)+[height[-1]]
def check(l,ori):
for i in range(1,len(l)):
if l[i]>l[i-1]:
l[i] = max(height[i],l[i-1])
return l
l=check(l,height)
l.reverse()
l = check(l,height.reverse())
l.reverse()
s =0
for i in range(len(height)):
s += l[i]-height[i]
print(s)
84.largest-rectangle-in-histogram 柱状图中最大的矩形
解题思路:
1.主要是超时问题
2.使用一个list来保存数值的位置
遍历heights:
如果栈为空或者当前值大于栈顶位置的值 则将这个位置放入栈中
如果当前值小于等于栈顶位置值 将栈顶的位置pop 计算这个值h能够产生的矩形面积
此时会用到pop后的栈顶位置posl[-1] 是h左边的边界 则面积为(i-posl[-1]-1)*h
开始时加入0 对最后的栈中情况进行处理
def largestRectangleArea1(heights):
"""
:type heights: List[int]
:rtype: int
"""
if not heights:
return 0
def check(h):
cur=0
ans=cur
for i in heights:
if i>=h:
cur+=1
else:
ans = max(ans,cur)
cur=0
ans = max(ans,cur)
return ans*h
ret = 0
for i in set(heights):
tmp=check(i)
ret = max(ret,tmp)
return ret
def largestRectangleArea(heights):
"""
:type heights: List[int]
:rtype: int
"""
posl =[]
ret = 0
heights.append(0)
n = len(heights)
for i in range(n):
if not posl or heights[i] > heights[posl[-1]]:
posl.append(i)
else:
while posl and heights[i] <= heights[posl[-1]]:
h = heights[posl[-1]]
posl.pop()
if not posl:
l = i
else:
l = i - posl[-1]-1
ret = max(ret, h * l)
posl.append(i)
return ret
85.maximal-rectangle 最大矩形
解题思路:
可以利用84中的方法
每一层网上看都能转换成84题中直方图求举证大小
每一层如果该层某一位置为0 则无论往上是否有1 改处在直方图中的值为0
def maximalRectangle(matrix):
"""
:type matrix: List[List[str]]
:rtype: int
"""
x = len(matrix)
ret =0
if x==0:
return 0
y = len(matrix[0])
def largestRectangleArea(heights):
posl =[]
ret = 0
heights.append(0)
n = len(heights)
for i in range(n):
if not posl or heights[i] > heights[posl[-1]]:
posl.append(i)
else:
while posl and heights[i] <= heights[posl[-1]]:
h = heights[posl[-1]]
posl.pop()
if not posl:
l = i
else:
l = i - posl[-1]-1
ret = max(ret, h * l)
posl.append(i)
return ret
for i in range(x):
height=[]
for j in range(y):
n = 0
tmpi = i
while matrix[tmpi][j]=="1" and tmpi>=0:
n+=1
tmpi-=1
height.append(n)
ret = max(ret,largestRectangleArea(height))
return ret
145.binary-tree-postorder-traversal 二叉树的后序遍历
解题思路:
后序遍历:左右根
取值时根右左,结果倒序
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
def postorderTraversal(root):
"""
:type root: TreeNode
:rtype: List[int]
"""
ret =[]
stack=[]
if not root:
return ret
stack.append(root)
while stack:
v = stack.pop()
if v.left:
stack.append(v.left)
if v.right:
stack.append(v.right)
ret.append(v.val)
ret.reverse()
return ret
224.basic-calculator 基本计算器
解题思路:
遍历str 放入stack中 同时将数字整合到一起 如果遇到‘)’ 则开始往前寻找’(’ 将经过的数值计算
非负整数 所以最后stack中第一个数必定为正整数 使用+
def calculate(s):
"""
:type s: str
:rtype: int
"""
stack=[]
ret = 0
numpre =""
for i in s:
if i==" ":
continue
if i!=")":
if i.isdigit():
numpre +=i
else:
if numpre!="":
stack.append(int(numpre))
numpre=""
stack.append(i)
else:
if numpre!="":
stack.append(int(numpre))
numpre=""
tmp = stack.pop()
pre = 0
res = 0
while tmp!="(":
if tmp=="+":
res +=pre
elif tmp=="-":
res -=pre
else:
pre = int(tmp)
tmp = stack.pop()
res+=pre
stack.append(res)
if numpre!="":
stack.append(int(numpre))
action = "+"
stack.append("+")
for i in stack:
if i in ("-","+"):
if action=="+":
ret +=pre
else:
ret -= pre
action =i
else:
pre = i
return ret
316.remove-duplicate-letters 去除重复字母
解题思路:
使用dic记录所有字母出现的次数
当往stack中添加字母x时,判断在他前面的字母是否比x大 而且在后面任然会出现
如果成立将这个字母从stack去除 继续往前判断
判断结束后 将x加入stack中 此时有的字母结果为resultset
当有字母已在前面放入了stack并保留了下来(在set内) 则可以不需再判断
def removeDuplicateLetters(s):
"""
:type s: str
:rtype: str
"""
dic = {}
for c in s:
dic[c] = dic.get(c,0)+1
resultSet = set()
stack = list()
for c in s:
dic[c] -= 1
if c in resultSet:
continue
while stack and stack[-1] > c and dic[stack[-1]]:
stack.pop()
stack.append(c)
resultSet = set(stack)
return ''.join(stack)