劍指 offer 07. 重建二叉樹 【難度:中等】
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。 例如,給出
前序遍歷 preorder = [3,9,20,15,7]
中序遍歷 inorder = [9,3,15,20,7]
返回如下的二叉樹:
3
/ \9 20
/ \
15 7
限制:
0 <= 節點個數 <= 5000
首先要明白前序、中序遍歷的順序是怎樣的。前序遍歷是根節點->左子樹->右子樹;中序遍歷是左子樹->根節點->右子樹。
所謂前、中、後是按根節點的遍歷位置來說的,前序就是根節點在前,然後是左右子樹;中序則是根節點夾在左右子樹之間。然後我們以上面的例子分析一下大致思路,根據前序遍歷的性質,根節點在前,我們首先能確定根節點為pre陣列中的第乙個,即3。
找到了根節點,我們又可以根據中序遍歷的性質,根節點分開左右子樹,然後就能進確定左子樹為9,右子樹為15,20,7。
即:從前序遍歷中找到首元素,為根節點,然後從中序遍歷中找到該根節點,左邊是左子樹、右邊是右子樹。
後面是遞迴繼續查詢子樹。
使用乙個 map 儲存中序遍歷的每個元素及其對應的下標,目的是為了快速獲得乙個元素在中序遍歷中的位置。呼叫遞迴方法,對於前序遍歷和中序遍歷,下標範圍都是從 0 到 n-1,其中 n 是二叉樹節點個數。
遞迴方法的基準情形有兩個:**判斷前序遍歷的下標範圍的開始和結束,若開始大於結束,則當前的二叉樹中沒有節點,返回空值 null。若開始等於結束,則當前的二叉樹中恰好有乙個節點,根據節點值建立該節點作為根節點並返回。若開始小於結束,則當前的二叉樹中有多個節點。**在前序遍歷中得到根節點的位置,從而得到左子樹和右子樹各自的下標範圍和節點數量,知道節點數量後,在前序遍歷中即可得到左子樹和右子樹各自的下標範圍,然後遞迴重建左子樹和右子樹,並將左右子樹的根節點分別作為當前根節點的左右子節點。
/**
* definition for a binary tree node.
* public class treenode
* }*/class
solution
//1.讀入中序陣列、記錄每個數在中序對應的原次序
mapindexmap =
newhashmap
();int length = preorder.length;
for(
int i =
0; i < length; i++
)//2.呼叫建樹遞迴
treenode tree=
buildtree
(preorder,
0, length -
1, inorder,
0, length -
1, indexmap)
;return tree;
}//前序序列、前序首元素下標、前序尾元素下標、中序佇列、中序首元素下標、中序尾元素下標、記錄次序的map
public treenode buildtree
(int
preorder,
int preorderstart,
int preorderend,
int[
] inorder,
int inorderstart,
int inorderend, map
indexmap)
int rootval = preorder[preorderstart]
;//在pre中找根節點,就是首元素。
treenode root =
newtreenode
(rootval)
;//建立新的首元素為根的新二叉樹、以遞迴進行。
if(preorderstart == preorderend)
else
}}
《劍指Offer》學習
1.賦值運算子過載函式的引數是函式所在類的const型別的引用 mystr operator const mystr str 賦值運算子 return this 1 加const是因為 2 用引用是因為 這樣可以避免在函式呼叫時對實參的一次拷貝,提高了效率。3 對於返回值 一般地,返回值是被賦值者的...
劍指offer學習記錄
原碼 機器碼 反碼 除符號位,各位取反 補碼 反碼加一 此時沒有符號位的概念,即符號位也參與運算 例子 於是補碼的出現,解決了0的符號以及兩個編碼的問題 1 1 1 1 0000 0001 原 1000 0001 原 0000 0001 補 1111 1111 補 0000 0000 補 0000 ...
劍指offer學習筆記
筆記主要記錄方法和知識點 知識點1 負數與補碼 乙個參考 知識點2 移位操作 右移 變小 按位 操作 知識點3 0xffffffff表示32位 1 o logn 的方法 非遞迴的快速冪,用到二進位制表示。在迴圈內注意base base。兩個指標等間距一起走。想明白斷開鍊錶這個事情,相當於操作是在原有...