LeetCode-棧-Hard
阿新 • • 發佈:2019-01-10
記錄了初步解題思路 以及本地實現程式碼;並不一定為最優 也希望大家能一起探討 一起進步
目錄
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)