根據一棵樹的前序遍歷與中序遍歷構造二叉樹。注意:你可以假設樹中沒有重複的元素。
前序拿到根節點,在中序中找到該節點左邊的元素和右邊的元素,遞迴下去.
public class offer_07
else if (index==inorderend-1)
else
return root;
}}
看了官方的遞迴解法,思路差不多,更簡潔一些:
class solution
// 前序遍歷中的第乙個節點就是根節點
int preorder_root = preorder_left;
// 在中序遍歷中定位根節點
int inorder_root = indexmap.get(preorder[preorder_root]);
// 先把根節點建立出來
treenode root = new treenode(preorder[preorder_root]);
// 得到左子樹中的節點數目
int size_left_subtree = inorder_root - inorder_left;
// 遞迴地構造左子樹,並連線到根節點
// 先序遍歷中「從 左邊界+1 開始的 size_left_subtree」個元素就對應了中序遍歷中「從 左邊界 開始到 根節點定位-1」的元素
root.left = mybuildtree(preorder, inorder, preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1);
// 遞迴地構造右子樹,並連線到根節點
// 先序遍歷中「從 左邊界+1+左子樹節點數目 開始到 右邊界」的元素就對應了中序遍歷中「從 根節點定位+1 到 右邊界」的元素
root.right = mybuildtree(preorder, inorder, preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right);
return root;
}public treenode buildtree(int preorder, int inorder)
return mybuildtree(preorder, inorder, 0, n - 1, 0, n - 1);
}}
遞迴能做的迭代也能做,只是更複雜、演算法比較巧妙,需要借助其他資料結構。思路:
對於前序中兩個連續節點x,y演算法流程:有兩個可能關係:
1.y是x的左兒子
2.y是x某個祖上的右兒子
1.我們用乙個棧和乙個指標輔助進行二叉樹的構造。初始時棧中存放了根節點(前序遍歷的第乙個節點),指標指向中序遍歷的第乙個節點;說明:1.我們依次列舉前序遍歷中除了第乙個節點以外的每個節點。如果 index 恰好指向棧頂節點,那麼我們不斷地彈出棧頂節點並向右移動 index,並將當前節點作為最後乙個彈出的節點的右兒子;如果 index 和棧頂節點不同,我們將當前節點作為棧頂節點的左兒子;
3.無論是哪一種情況,我們最後都將當前的節點入棧。
棧:當前節點的所有還沒有考慮右兒子的祖先節點。(棧頂是當前節點)
指標:當前節點不斷往左走的最終節點。
**:class solution else
node.right = new treenode(preorderval);
stack.push(node.right);}}
return root;
}}
leetcode 105 前序,中序建樹
有簡潔版的。可是懶得看。自己寫的這個算是模擬手痠過程了吧,恩。感覺碰到這樣的例子,就是涉及長度加減的,都要拿小資料測一測。class solution int mid 1 for int i ll i rr i if inorder i root val root left find l 1,l m...
LeetCode 105 前序和中序構建二叉樹
給定乙個二叉樹前序遍歷陣列a 124367,中序遍歷得到陣列b,421637。我們的任務是從這兩個結果中構造出原來二叉樹。根據前序遍歷的順序,可以知道陣列是先存放根,然後是左子樹,最後是右子樹。根據中序遍歷的順序,可以知道陣列是先放左子樹,然後是根,最後是右子樹。根據定義,前序遍歷陣列第乙個位置是根...
前序中序後序
遍歷情況 前序 根結點 左子樹 右子樹 中序 左子樹 根結點 右子樹 後序 左子樹 右子樹 根結點 例題一 輸入描述 input description 輸入檔案共2行,第一行表示該樹的前序遍歷結果,第二行表示該樹的後序遍歷結果。輸入的字符集合為,長度不超過26。輸出描述 output descri...