1、樹的子結構
題目描述:
輸入兩棵二叉樹A,B,判斷B是不是A的子結構。(ps:我們約定空樹不是任意一個樹的子結構)
思路:
- 遞歸判斷,其中一個函數hasSubTree判讀一個樹是不是另一個樹的子樹,函數isSubTree判斷兩棵樹是不是相等,根節點相等則判斷左右子樹是否相等。
代碼:
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
if(root1==null||root2==null)
return false;
else return HasSubtree(root1.left,root2)||HasSubtree(root1.right,root2)||isSubTree(root1,root2);
}
private boolean isSubTree(TreeNode root1,TreeNode root2){
if(root2==null)
return true;
if(root1==null)
return false;
else if(root1.val==root2.val)
return isSubTree(root1.left,root2.left)&&isSubTree(root1.right,root2.right);
return false;
}
}
2、重建二叉樹
題目描述:
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。
思路:
- 前序遍歷數組pre數組,中序遍歷數組in數組,pre數組第一個數組即爲根節點,遍歷in數組找到根節點所在位置,則in數組中根節點左邊即爲左子樹,右邊即爲右子樹。
代碼:
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
TreeNode root = reConstructBinaryTreeAs(pre,0,pre.length-1,in,0,in.length-1);
return root;
}
private TreeNode reConstructBinaryTreeAs(int [] pre,int preStart,int preEnd,int [] in,int inStart,int inEnd){
if(preEnd<preEnd||inEnd<inStart)
return null;
TreeNode root = new TreeNode(pre[preStart]);
for(int i=inStart;i<=inEnd;i++){
if(in[i]==root.val){
root.left = reConstructBinaryTreeAs
(pre,preStart+1,preStart+i-inStart,in,inStart,i-1);
root.right = reConstructBinaryTreeAs
(pre,i-inStart+preStart+1,preEnd,in,i+1,inEnd);
break;
}
}
return root;
}
}
3、二叉樹的鏡像
題目描述:
操作給定的二叉樹,將其變換爲源二叉樹的鏡像。
輸入描述:
二叉樹的鏡像定義:源二叉樹
8
/
6 10
/ \ /
5 7 9 11
鏡像二叉樹
8
/
10 6
/ \ /
11 9 7 5
思路:
- 交換左右子樹,遞歸交換直到左右子樹都爲空。
代碼:
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public void Mirror(TreeNode root) {
if(root==null||(root.left==null&&root.right==null))
return;
TreeNode p = root.left;
root.left = root.right;
root.right = p;
Mirror(root.left);
Mirror(root.right);
}
}
3、從上往下打印二叉樹
題目描述:
從上往下打印出二叉樹的每個節點,同層節點從左至右打印。
思路:
- 藉助一個隊列,一個list,根節點入隊列,每次從隊列中彈出一個元素,將這個元素add進list中,同時在隊列中把當前節點的左右子樹入隊列。
代碼:
import java.util.ArrayList;
import java.util.Queue;
import java.util.LinkedList;
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
ArrayList<Integer> list = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
if(root==null) return list;
queue.add(root);
while(!queue.isEmpty()){
TreeNode k = queue.poll();
list.add(k.val);
if(k.left!=null)
queue.add(k.left);
if(k.right!=null)
queue.add(k.right);
}
return list;
}
}
4、二叉搜索樹的後序遍歷序列
題目描述:
輸入一個整數數組,判斷該數組是不是某二叉搜索樹的後序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數組的任意兩個數字都互不相同。
思路:
後序遍歷,根節點爲最後一個元素,左子樹的元素都小於根節點,右子樹的元素都大於根節點,遍歷數組。
代碼:
public class Solution {
public boolean VerifySquenceOfBST(int [] sequence) {
int n = sequence.length;
if(n==0) return false;
return rejudge(sequence,0,n-1);
}
private boolean rejudge(int [] sequence,int start,int len){
if(start>=len)
return true;
int n = sequence[len];
int i=start;
while(i<=n&&sequence[i]<sequence[len])
i++;
for(int j=i;j<=len;j++){
if(sequence[j]<sequence[len])
return false;
}
return rejudge(sequence,0,i-1)&&rejudge(sequence,i,len-1);
}
}
5、二叉樹中和爲某一值的路徑
題目描述:
輸入一顆二叉樹的根節點和一個整數,打印出二叉樹中結點值的和爲輸入整數的所有路徑。路徑定義爲從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。(注意: 在返回值的list中,數組長度大的數組靠前)
思路:
- 先序遍歷 遞歸
代碼:
import java.util.ArrayList;
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
private ArrayList<ArrayList<Integer>> list1 = new ArrayList<ArrayList<Integer>>();
private ArrayList<Integer> list2 = new ArrayList<>();
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
if(root==null)
return list1;
list2.add(root.val);
target = target-root.val;
if(target==0&&root.left==null&&root.right==null)
list1.add(new ArrayList<Integer>(list2));
FindPath(root.left,target);
FindPath(root.right,target);
list2.remove(list2.size()-1);
return list1;
}
}
6、二叉樹的深度
題目描述:
輸入一棵二叉樹,求該樹的深度。從根結點到葉結點依次經過的結點(含根、葉結點)形成樹的一條路徑,最長路徑的長度爲樹的深度。
思路:
- 遞歸,往下遞歸一層,左子樹和右子樹的深度都加1,然後返回值更大的。
代碼:
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public int TreeDepth(TreeNode root) {
if(root==null)
return 0;
int left = TreeDepth(root.left);
int right = TreeDepth(root.right);
return Math.max(left,right)+1;
}
}
7、平衡二叉樹
題目描述:
輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。
思路:
平衡二叉樹:它是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹。
代碼:
public class Solution {
public boolean IsBalanced_Solution(TreeNode root) {
if(root==null)
return true;
return Math.abs(treeDepth(root.left)-treeDepth(root.right))<=1&&
IsBalanced_Solution(root.left)&&IsBalanced_Solution(root.right);
}
private int treeDepth(TreeNode root){
if(root==null)
return 0;
else return Math.max(treeDepth(root.left),treeDepth(root.right))+1;
}
}
8、二叉樹的下一個結點
題目描述:
給定一個二叉樹和其中的一個結點,請找出中序遍歷順序的下一個結點並且返回。注意,樹中的結點不僅包含左右子結點,同時包含指向父結點的指針。
思路:
分析二叉樹的下一個節點,一共有以下情況:
1.二叉樹爲空,則返回空;
2.節點右孩子存在,則設置一個指針從該節點的右孩子出發,一直沿着指向左子結點的指針找到的葉子節點即爲下一個節點;
3.節點不是根節點。如果該節點是其父節點的左孩子,則返回父節點;否則繼續向上遍歷其父節點的父節點,重複之前的判斷,返回結果。
代碼:
/*
public class TreeLinkNode {
int val;
TreeLinkNode left = null;
TreeLinkNode right = null;
TreeLinkNode next = null;
TreeLinkNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public TreeLinkNode GetNext(TreeLinkNode pNode)
{
if(pNode.right!=null){
TreeLinkNode p = pNode.right;
if(p.left!=null){
while(p.left!=null)
p = p.left;
}
return p;
}
else if(pNode.next!=null&&pNode.next.left == pNode)
return pNode.next;
else if(pNode.next!=null){
TreeLinkNode p1 = pNode;
while(p1.next.left!=p1){
p1 = p1.next;
if(p1.next==null)
return null;
}
return p1.next;
}
return null;
}
}
9、對稱的二叉樹
題目描述:
請實現一個函數,用來判斷一顆二叉樹是不是對稱的。注意,如果一個二叉樹同此二叉樹的鏡像是同樣的,定義其爲對稱的。
思路:
代碼:
10、按之字形順序打印二叉樹
題目描述:
請實現一個函數按照之字形打印二叉樹,即第一行按照從左到右的順序打印,第二層按照從右至左的順序打印,第三行按照從左到右的順序打印,其他行以此類推。
思路:
代碼:
11、把二叉樹打印成多行
題目描述:
從上到下按層打印二叉樹,同一層結點從左至右輸出。每一層輸出一行。
思路:
代碼:
12、序列化二叉樹
題目描述:
*請實現兩個函數,分別用來序列化和反序列化二叉樹
二叉樹的序列化是指:把一棵二叉樹按照某種遍歷方式的結果以某種格式保存爲字符串,從而使得內存中建立起來的二叉樹可以持久保存。序列化可以基於先序、中序、後序、層序的二叉樹遍歷方式來進行修改,序列化的結果是一個字符串,序列化時通過 某種符號表示空節點(#),以 ! 表示一個結點值的結束(value!)。
二叉樹的反序列化是指:根據某種遍歷順序得到的序列化字符串結果str,重構二叉樹。*
思路:
代碼:
13、二叉搜索樹的第k個結點
題目描述:
給定一棵二叉搜索樹,請找出其中的第k小的結點。例如, (5,3,7,2,4,6,8) 中,按結點數值大小順序第三小結點的值爲4。
思路:
代碼: