1,三大基礎遍曆方式
三個遍曆的部落格地址,
1)<LeetCode OJ> 144/145/94 Binary Tree (Pre & In & Post) order Traversal
即:
前序走訪,總是先訪問當前節點,再左子,最後右子
中序遍曆,總是先訪問左子,再當前節點,最後右子
後序遍曆,總是先訪問左子,再右子,最後當前節點
關於三大基礎遍曆,必須要條件反射式的記住:三種遍曆的迭代方式使用的都是棧,後序遍曆必須使用了兩個棧,其餘亂七八糟的解決方式統統就不要再記了。
2,廣度遍曆
三道中序遍曆題目:
1)<LeetCode OJ> 102. / 107. Binary Tree Level Order Traversal(I / II)
分析:
102題目的意思是每一層均按照從左至右的順序遍曆節點,並記錄節點到vector中。顯然廣度優先搜尋,用隊列。
利用兩個隊列儲存當層的節點與下一層的節點,下一層的元素處理完後,
下一層成為當層(繼續擷取下一層的節點)。
107題目道理是一樣的,不過就是插入vector的順序逆著來而已,不過這樣做似乎沒有達到考察的目的。
2)<LeetCode OJ> 103. Binary Tree Zigzag Level Order Traversal
這個問題和上面的題目基本一樣,唯一的區別就是奇數層和偶數層的壓入順序相反而已,但是通過vector插入順序的不同來達到目的似乎並沒有達到題目的考察目的。
102/103/107三個題目,都是按照廣度優先遍曆二叉樹,其實主要用到資料結構隊列。演算法這裡不細說了,可以直接看文章中的代碼。
顯然,中序遍曆必須要條件反射的是,務必使用資料結構隊列。
3,構造二叉樹 1)<LeetCode OJ> 106. Construct Binary Tree from Inorder and Postorder Traversal 2)<LeetCode OJ> 105. Construct Binary Tree from Preorder and Inorder Traversal
分析:
首先要弄清楚什麼是前序走訪和中序遍曆,後續遍曆?
前序走訪就是先遍曆當前的節點,然後遍曆該節點的左分支(即遍曆左分支的所有節點),最後再遍曆該節點的右分支。
中序遍曆是先遍曆當前節點的左分支,再遍曆當前節點,最後遍曆當前節點的右分支。
還有後序遍曆,就是先左分支,再右分支,最後當前節點。
以下面的二叉樹為例。
4
/ \
2 7
/ \ / \
1 3 6 9
其先序遍曆結果:【4 2 1 3 7 6 9】
中序遍曆結果是:【1 2 3 4 6 7 9】
後序遍曆結果是:【1 3 2 6 9 7 4】
對先序遍曆來說:
先序遍曆的每個值表示的結點都是接下來的若干個結點(根據中序遍曆即確定)的父結點。
比如【4】是這個二叉樹的根結點,【2】是【1 3】的父結點,【1】是 空的父結點,也即使葉子結點。
對中序遍曆來說:
根結點(根據前序走訪即確定)一定在中間位置,該位置左邊是其左子樹,右邊是其右子樹。
比如【4】左邊【1 2 3】全是根結點的左子樹,右邊是【6 7 9】是根結點的右子樹。
對於【2】來說,【1】是其左子樹,【3】是其右子樹。
對後序遍曆來說:
後序遍曆的末尾結點都是前面的若干個結點(根據中序遍曆即可確定)的父結點。
比如【4】是這個二叉樹的根結點,【2】是【1 3】的父結點,【7】是【4 6】的父結點,
……
依次類推。
很明顯,這是一個遞迴過程。
4,二叉樹的平衡
博文地址:
1)判斷一顆二叉樹是否平衡,<LeetCode OJ> 110. Balanced Binary Tree
2)根據有序鏈表和數組構造二叉搜尋樹,<LeetCode OJ> 109 / 108 Convert Sorted ( List / Array ) to Binary Search Tree
有序數組或者鏈錶轉化成二叉搜尋樹。思路還是比較明顯的。因為有序,為了能平衡,總是選擇數組或者(未被使用過的位置的)中間位置的值作為當前二叉樹的根節點。顯然對於鏈表來說就是使用快慢指標法來找到中間位置。
5,枚舉二叉搜尋樹
見博文:
1)符合要求的二叉搜尋樹有多少種。,<LeetCode OJ> 96. Unique Binary Search Trees
這個問題實際上是動態規劃問題,所以必須努力去找到和以前的子問題的聯絡。
斷言:由1,2,3,...,n構建的二叉尋找樹,以i為根節點,左子樹由[1,i-1]構成,其右子樹由[i+1,n]構成。
定義子問題:定義f(i)為以[1,i]能產生的二叉搜尋樹的數目
若數組為空白,則只有一種BST,即空樹,f(0)=1;
若數組僅有一個元素1,單個節點,f(1)=1;
若數組有兩個元素1,2,則有兩種可能,f(2)=2;
若數組有三個元素1,2,3,則有5中情況,題目已經說了,
n=4呢。顯示此問題玄機的時候到了:尋找與上面已推出子問題的關係:
如果1為根,則左子樹0個元素所以1種情況,右子樹3個元素(2,3,4),顯然為5種情況
如果2為根,則左子樹1個元素所以1種情況,右子樹2個元素(3,4),顯然為2
如果3為根,則左子樹2個元素所以2種情況,右子樹1個元素(4),顯然為1
如果4為根,則左子樹3個元素所以5種情況,右子樹3個元素(無),顯然為1
由此可以得到遞推公式:f(i)=f(0)*f(i-1)+...+f(k-1)*f(i-k)+...+f(i-1)*f(0)
2,Unique Binary Search Trees II
6,二叉樹結構變更
博文如下:
1)反轉二叉樹,<LeetCode OJ> 226. Invert Binary Tree
2)二叉樹是否鏡像對稱。,<LeetCode OJ> 101. Symmetric Tree
3)將二叉樹碾平成單鏈表,<LeetCode OJ> 114. Flatten Binary Tree to Linked List
4)右視二叉樹的結果, <LeetCode OJ> 116 / 117 Populating Next Right Pointers in Each Node (I / II)
7,結構特徵判斷 兩顆二叉樹是否一樣,
1)<LeetCode OJ> 100. Same Tree
8,二叉樹路徑判斷 1)<LeetCode OJ> 235. / 236. LCA of a BSTree & BTree
對於235題,因為是在一顆二叉搜尋樹中(左右子具有大小關係),那麼我們只需要關注祖先節點r和q、p的關係即可。
注意:本題給定的兩個節點一定在這個二叉搜尋樹上,所以一定存在最低公用祖先。
如果當前節點r是q和p的祖先,一定滿足如下條件:
1)p和q分居兩顆子樹
2)p和q中有一個就是當前節點,另一個居於某顆子樹
那麼其他情況呢。
3)p和q都在左子樹或者右子樹
而根據二叉搜尋樹的規則,我們可以通過比較三個節點的大小來判斷誰在誰的那一邊
對於236題:思路就是記錄從根節點達到p和q的兩條路徑,顯然知道了兩條路徑之後,不相同的上一個節點就是最低公用祖先。 比如4和2的: 4的路徑:3,5,2,4 2的路徑:3,5,2
<LeetCode OJ> 129. Sum Root to Leaf Numbers
Total Accepted: 74843 Total Submissions: 229553 Difficulty: Medium
Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.
An example is the root-to-leaf path 1->2->3 which represents the number 123.
Find the total sum of all root-to-leaf numbers.
For example,
1 / \ 2 3
The root-to-leaf path 1->2 represents the number 12.
The root-to-leaf path 1->3 represents the number 13.
Return the sum = 12 + 13 = 25.
分析:DONE
深度優先搜尋。累加當前節點的值,一旦遇到葉子就加到sum裡,最後統計出總和。 [cpp] view plain copy print ? /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution {