vue 倒序遍历数组_【一天一大 lee】从中序与后序遍历序列构造二叉树 (难度:中等)Day20200925...
生活随笔
收集整理的這篇文章主要介紹了
vue 倒序遍历数组_【一天一大 lee】从中序与后序遍历序列构造二叉树 (难度:中等)Day20200925...
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
20200925
后序遍歷?postorder?=?[9,15,7,20,3]
???/?\
??9??20
????/??\
???15???7
后序遍歷數組倒序遍歷依次作為根節點 當前根節點的的左右子節點從中序遍歷數組中查找:
?*?Definition?for?a?binary?tree?node.
?*?function?TreeNode(val)?{
?*?????this.val?=?val;
?*?????this.left?=?this.right?=?null;
?*?}
?*/
/**
?*?@param?{number[]}?inorder??中序遍歷
?*?@param?{number[]}?postorder?后序遍歷
?*?@return?{TreeNode}
?*/
var?buildTree?=?function(inorder,?postorder)?{
??let?rootIndex?=?postorder.length?-?1,
????map?=?new?Map()
??//?記錄在中序遍歷數組中每個節點的位置,方便在得到根節點時查找左右子樹節點
??for?(let?i?=?0;?i?????map.set(inorder[i],?i)
??}
??function?dfs(leftIndex,?rightIndex)?{
????if?(leftIndex?>?rightIndex)?return?null
????let?root?=?new?TreeNode(postorder[rootIndex]),
??????i?=?map.get(postorder[rootIndex])
????rootIndex--
????root.right?=?dfs(i?+?1,?rightIndex)
????root.left?=?dfs(leftIndex,?i?-?1)
????return?root
??}
??return?dfs(0,?inorder.length?-?1)
}
b 是 a 的右子樹上的節點 a 沒有右子樹,并且 b 是與 a 子樹相連的的左子樹上的節點
??let?rootIndex?=?postorder.length?-?1,
????root?=?new?TreeNode(postorder[rootIndex]),
????//?維護下一次遍歷追擊子樹的最新子樹
????queue?=?[root],
????inorderIndex?=?inorder.length?-?1
??rootIndex--
??while?(rootIndex?>=?0)?{
????let?node?=?queue[queue.length?-?1],
??????nodeVal?=?postorder[rootIndex]
????//?不等于上一個生成子樹的節點,則說明是上一個子樹的右節點
????if?(node.val?!==?inorder[inorderIndex])?{
??????node.right?=?new?TreeNode(nodeVal)
??????queue.push(node.right)
????}?else?{
??????//?維護inorder的倒序遍歷索引跳過已經生成樹的根節點
??????while?(
????????queue.length?&&
????????queue[queue.length?-?1].val?===?inorder[inorderIndex]
??????)?{
????????node?=?queue.pop()
????????inorderIndex--
??????}
??????//?情況?2
??????node.left?=?new?TreeNode(nodeVal)
??????queue.push(node.left)
????}
????rootIndex--
??}
??return?root
}
題目:[1]
根據一棵樹的中序遍歷與后序遍歷構造二叉樹。
注意:你可以假設樹中沒有重復的元素。
例如,給出:
中序遍歷?inorder?=?[9,3,15,20,7]后序遍歷?postorder?=?[9,15,7,20,3]
返回如下的二叉樹:
????3???/?\
??9??20
????/??\
???15???7
拋磚引玉
拋磚引玉思路
參數:
- 中序遍歷的數組
- 后續遍歷的數組
思路
- 借助后續遍歷的節點找到每層子樹的根節點
- rootIndex:二叉子樹在后續遍歷數組中的位置索引
- leftIndex:二叉子樹的左子樹在后續遍歷數組中的位置索引
- rightIndex:二叉子樹的右子樹在后續遍歷數組中的位置索引
查找根節點,及當前根節點左右子節點的邏輯:
- 這個節點的左節點在中序遍歷數組中這個元素的前一位
- 這個節點的右節點在中序遍歷數組中這個元素的后一位
深度優先搜索(DFS)
遞歸參數:
- 左子樹根節點在 postorder 中的索引
- 右子樹根節點在 postorder 中的索引
終止條件:
因為后續遍歷是先遍歷左子樹再遍歷右子樹最后遍歷根節點, 那么右子樹的索引一定大于左子樹的索引,當不滿足是說明節點遍歷完成,終止遞歸
/**?*?Definition?for?a?binary?tree?node.
?*?function?TreeNode(val)?{
?*?????this.val?=?val;
?*?????this.left?=?this.right?=?null;
?*?}
?*/
/**
?*?@param?{number[]}?inorder??中序遍歷
?*?@param?{number[]}?postorder?后序遍歷
?*?@return?{TreeNode}
?*/
var?buildTree?=?function(inorder,?postorder)?{
??let?rootIndex?=?postorder.length?-?1,
????map?=?new?Map()
??//?記錄在中序遍歷數組中每個節點的位置,方便在得到根節點時查找左右子樹節點
??for?(let?i?=?0;?i?????map.set(inorder[i],?i)
??}
??function?dfs(leftIndex,?rightIndex)?{
????if?(leftIndex?>?rightIndex)?return?null
????let?root?=?new?TreeNode(postorder[rootIndex]),
??????i?=?map.get(postorder[rootIndex])
????rootIndex--
????root.right?=?dfs(i?+?1,?rightIndex)
????root.left?=?dfs(leftIndex,?i?-?1)
????return?root
??}
??return?dfs(0,?inorder.length?-?1)
}
迭代
倒序遍歷中序遍歷數組(inorder):
- 二叉樹的遍歷邏輯變成了:先遍歷右孩子,再遍歷根節點,最后遍歷左孩子
倒序遍歷后序遍歷數組(postorder):
- 二叉樹的遍歷邏輯變成了:先遍歷根節點,再遍歷右孩子,最后遍歷左孩子
那么,倒序遍歷后序遍歷數組數組時,兩個相鄰的節點[a,b],兩個節點在二叉樹中的關系:
實現
postorder 中最后一個元素是整個二叉樹的根節點
倒序遍歷 postorder,inorder:
inorder 中先遇到右子樹上的節點:
- 不等于上一個生成子樹的節點,則說明是上一個子樹的右節點即情況 1,生成子樹追擊到上一個子樹的 right 上
- 等于上一個生成子樹的節點,則說明在 inorder 中遍歷到了根節點,即情況 2,那么 inorder 繼續遍歷先遇到的應該是這個根節點對應子樹的左節點
??let?rootIndex?=?postorder.length?-?1,
????root?=?new?TreeNode(postorder[rootIndex]),
????//?維護下一次遍歷追擊子樹的最新子樹
????queue?=?[root],
????inorderIndex?=?inorder.length?-?1
??rootIndex--
??while?(rootIndex?>=?0)?{
????let?node?=?queue[queue.length?-?1],
??????nodeVal?=?postorder[rootIndex]
????//?不等于上一個生成子樹的節點,則說明是上一個子樹的右節點
????if?(node.val?!==?inorder[inorderIndex])?{
??????node.right?=?new?TreeNode(nodeVal)
??????queue.push(node.right)
????}?else?{
??????//?維護inorder的倒序遍歷索引跳過已經生成樹的根節點
??????while?(
????????queue.length?&&
????????queue[queue.length?-?1].val?===?inorder[inorderIndex]
??????)?{
????????node?=?queue.pop()
????????inorderIndex--
??????}
??????//?情況?2
??????node.left?=?new?TreeNode(nodeVal)
??????queue.push(node.left)
????}
????rootIndex--
??}
??return?root
}
博客: 小書童博客[2]
每天的每日一題,寫的題解會同步更新到公眾號一天一大 lee 欄目 歡迎關注留言
前端小書童參考資料
[1]題目:: https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/
[2]小書童博客: http://gaowenju.com/
總結
以上是生活随笔為你收集整理的vue 倒序遍历数组_【一天一大 lee】从中序与后序遍历序列构造二叉树 (难度:中等)Day20200925...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c 冒泡排序_C语言中选择排序和冒泡排序
- 下一篇: python可以在哪些平台安装_pyth