題目來源於 LeetCode 第 144 號問題:二叉樹的前序遍歷。java
給定一個二叉樹,返回它的 前序 遍歷。node
用**棧(Stack)**的思路來處理問題。算法
前序遍歷的順序爲根-左-右,具體算法爲:數組
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
List<Integer> list = new LinkedList<>();
if(root == null){
return list;
}
//第一步是將根節點壓入棧中
stack.push(root);
//當棧不爲空時,出棧的元素插入list尾部。
while(!stack.isEmpty()){
root = stack.pop();
list.add(root.val);
if(root.right != null) stack.push(root.right);
if(root.left != null) stack.push(root.left);
}
return list;
}
}
複製代碼
題目來源於 LeetCode 第 94 號問題:二叉樹的中序遍歷。緩存
給定一個二叉樹,返回它的 中序 遍歷。bash
用**棧(Stack)**的思路來處理問題。post
中序遍歷的順序爲左-根-右,具體算法爲:動畫
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
if (cur != null) {
stack.push(cur);
cur = cur.left;
} else {
cur = stack.pop();
list.add(cur.val);
cur = cur.right;
}
}
return list;
}
}
複製代碼
題目來源於 LeetCode 第 145 號問題:二叉樹的後序遍歷。spa
給定一個二叉樹,返回它的 後序 遍歷。3d
用**棧(Stack)**的思路來處理問題。
後序遍歷的順序爲左-右-根,具體算法爲:
public class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if(root == null)
return res;
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode node = stack.pop();
if(node.left != null) stack.push(node.left);//和傳統先序遍歷不同,先將左結點入棧
if(node.right != null) stack.push(node.right);//後將右結點入棧
res.add(0,node.val); //逆序添加結點值
}
return res;
}
}
複製代碼
題目來源於 LeetCode 第 102 號問題:二叉樹的層序遍歷。
給定一個二叉樹,返回其按層次遍歷的節點值。 (即逐層地,從左到右訪問全部節點)。
例如: 給定二叉樹: [3,9,20,null,null,15,7]
,
3
/ \
9 20
/ \
15 7
複製代碼
返回其層次遍歷結果:
[
[3],
[9,20],
[15,7]
]
複製代碼
該問題須要用到隊列。
public List<List<Integer>> levelOrder(TreeNode root) {
if(root == null)
return new ArrayList<>();
List<List<Integer>> res = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
while(!queue.isEmpty()){
int count = queue.size();
List<Integer> list = new ArrayList<Integer>();
while(count > 0){
TreeNode node = queue.poll();
list.add(node.val);
if(node.left != null)
queue.add(node.left);
if(node.right != null)
queue.add(node.right);
count--;
}
res.add(list);
}
return res;
}
複製代碼
題目來源於 LeetCode 第 110 號問題:平衡二叉樹。
給定一個二叉樹,判斷它是不是高度平衡的二叉樹。
採起後序遍歷的方式遍歷二叉樹的每個結點。
在遍歷到一個結點以前已經遍歷了它的左右子樹,那麼只要在遍歷每一個結點的時候記錄它的深度(某一結點的深度等於它到葉結點的路徑的長度),就能夠一邊遍歷一邊判斷每一個結點是否是平衡的。
class Solution {
private boolean isBalanced = true;
public boolean isBalanced(TreeNode root) {
getDepth(root);
return isBalanced;
}
public int getDepth(TreeNode root) {
if (root == null)
return 0;
int left = getDepth(root.left);
int right = getDepth(root.right);
if (Math.abs(left - right) > 1) {
isBalanced = false;
}
return right > left ? right + 1 : left + 1;
}
}
複製代碼
題目來源於 LeetCode 第 101 號問題:對稱二叉樹。
給定一個二叉樹,檢查它是不是鏡像對稱的。
例如,二叉樹 [1,2,2,3,4,4,3]
是對稱的。
1
/ \
2 2
/ \ / \
3 4 4 3
複製代碼
用遞歸作比較簡單:一棵樹是對稱的等價於它的左子樹和右子樹兩棵樹是對稱的,問題就轉變爲判斷兩棵樹是否對稱。
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) return true;
//把問題變成判斷兩棵樹是不是對稱的
return isSym(root.left, root.right);
}
//判斷的是根節點爲r1和r2的兩棵樹是不是對稱的
public boolean isSym(TreeNode r1, TreeNode r2){
if(r1 == null && r2 == null) return true;
if(r1 == null || r2 == null) return false;
//這兩棵樹是對稱須要知足的條件:
//1.倆根節點相等。 2.樹1的左子樹和樹2的右子樹,樹2的左子樹和樹1的右子樹都得是對稱的
return r1.val == r2.val && isSym(r1.left, r2.right)
&& isSym(r1.right, r2.left);
}
}
複製代碼
題目來源於 劍指 offer :重建二叉樹。
根據二叉樹的前序遍歷和中序遍歷的結果,重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。
preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]
複製代碼
前序遍歷的第一個值爲根節點的值,使用這個值將中序遍歷結果分紅兩部分,左部分爲樹的左子樹中序遍歷結果,右部分爲樹的右子樹中序遍歷的結果。
// 緩存中序遍歷數組每一個值對應的索引
private Map<Integer, Integer> indexForInOrders = new HashMap<>();
public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
for (int i = 0; i < in.length; i++)
indexForInOrders.put(in[i], i);
return reConstructBinaryTree(pre, 0, pre.length - 1, 0);
}
private TreeNode reConstructBinaryTree(int[] pre, int preL, int preR, int inL) {
if (preL > preR)
return null;
TreeNode root = new TreeNode(pre[preL]);
int inIndex = indexForInOrders.get(root.val);
int leftTreeSize = inIndex - inL;
root.left = reConstructBinaryTree(pre, preL + 1, preL + leftTreeSize, inL);
root.right = reConstructBinaryTree(pre, preL + leftTreeSize + 1, preR, inL + leftTreeSize + 1);
return root;
}
複製代碼