這篇文章總結一些遞歸常見的優化方法
以題目來說,leetcode 106,已知中序和後序遍歷,構造二叉樹
方法一:傳入數組爲參數
#中序遍歷 左 根 右
#後序遍歷 左 右 根
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
n=len(inorder)
if n==0:
return None
if n==1:
return TreeNode(inorder[0])
#後序遍歷的最後一個是根
root=TreeNode(postorder[-1])
for i in range(n):
if inorder[i]==root.val:
break;
root.left=self.buildTree(inorder[:i],postorder[:i])
root.right=self.buildTree(inorder[i+1:],postorder[i:-1])
return root
方法一優化後
其實就加了兩個優化
1.用哈希表存儲索引 不需要每次都O(n)的搜索 只要O(1)
2.傳參數不傳數組了,每次只傳入四個int型的變量
沒想到結果快了10倍
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
def helper(in_left,in_right,post_left,post_right):
if in_left>in_right or post_left>post_right:
return None
if in_left==in_right:
return TreeNode(inorder[in_left])
root=TreeNode(postorder[post_right])
#通過hash表存儲 不要反覆查找
i=hashmap[root.val]
k=i-1+post_left-in_left
root.left=helper(in_left,i-1,post_left,k)
root.right=helper(i+1,in_right,k+1,post_right-1)
return root
#優化方法 把中序遍歷的值放在hash表中
#一種很帥的字典生成方法
hashmap={element:i for i,element in enumerate(inorder)}
if len(inorder)==0:
return None
return helper(0,len(inorder)-1,0,len(postorder)-1)
最後留下了一個疑問:到底是hashmap優化加速快還是傳參問題?暫時沒想出來
今天遞歸犯了一個很蠢的錯誤 debug至少半個小時…
這個該死的return沒寫 導致這一小段遞歸沒有返回值 而且一直沒發現…吐血
if tmpSum==avg:
return dfs(k-1,0,0) #重新返回最初的起點 開始湊
這個湊子集不反轉要超時 就這一句話
#不加revese要超時
nums.sort(reverse=True)