二叉樹遍歷
先序遍歷
遞歸
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list=new ArrayList<>();
if(root==null){
return list;
}
helper(list,root);
return list;
}
public void helper(List<Integer> list,TreeNode root){
if(root==null){
return;
}
list.add(root.val);
helper(list,root.left);
helper(list,root.right);
}
}
迭代
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list=new ArrayList<>();
if(root==null){
return list;
}
Stack<TreeNode> stack=new Stack<>();
while(root!=null||!stack.isEmpty()){
if(root!=null){
list.add(root.val);
stack.push(root);
root=root.left;
}else{
root=stack.pop();
root=root.right;
}
}
return list;
}
}
樹的子結構
實質上也是考察的二叉樹的遍歷
主要分爲兩步:
第一步:
遍歷二叉樹找A與B
class Solution{
public boolean isSubStructure(TreeNode A,TreeNode B){
boolean res=false;
if(A!=null&&B!=null){
if(A.val==B.val){
res=doesTreeAhasB(A,B);
}
if(!res){
res=isSubStructure(A.left,B);
}
if(!res){
res=isSubStructure(A.right,B);
}
}
return res;
}
boolean doesTreeAhasB(TreeNode A,TreeNode B){
if(B==null){
return true;
}
if(A==null){
return false;
}
if(A.val!=B.val){
return false;
}
return doesTreeAhasB(A.left,B.left)&&doesTreeAhasB(A.right,B.right);
}
}
二叉樹中和爲某一值的路徑
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int sum) {
List<List<Integer> > lists=new ArrayList<>();
//判非
if(root==null){
return lists;
}
List<Integer> list=new ArrayList<>();
countPathSum(root,sum,lists,list);
return lists;
}
public void countPathSum(TreeNode root,int sum,List<List<Integer> > lists,List<Integer> list){
//判斷遞歸終止條件
if(root==null){
return;
}
//當前要執行的操作
sum-=root.val;
list.add(root.val);
//如果該節點爲葉子節點並且sum爲0,則加入路徑
if(sum==0&&root.left==null&&root.right==null){
lists.add(new ArrayList(list));
}
//更深層次的遍歷
countPathSum(root.left,sum,lists,list);
countPathSum(root.right,sum,lists,list);
//重置
sum+=root.val;
list.remove(list.size()-1);
}
}
124. 二叉樹中的最大路徑和
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private int max=Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
if(root==null){
return 0;
}
maxPath(root);
return max;
}
public int maxPath(TreeNode node){
if(node==null){
return 0;
}
int leftmax=Math.max(maxPath(node.left),0);//如果是負值 則貢獻值置爲0
int rightmax=Math.max(maxPath(node.right),0);
max=Math.max(max,leftmax+rightmax+node.val);
return node.val+Math.max(leftmax,rightmax); //只能有一邊可以參與到路徑
}
}
二叉樹節點之間的最大距離問題
二叉樹節點間的最大距離問題
題目描述:
從二叉樹的節點 A 出發,可以向上或者向下走,但沿途的節點只能經過一次,當到達節點 B 時,路徑上的節點數叫作 A 到 B 的距離。
現在給出一棵二叉樹,求整棵樹上每對節點之間的最大距離。
輸入描述:
第一行輸入兩個整數 n 和 root,n 表示二叉樹的總節點個數,root 表示二叉樹的根節點。
以下 n 行每行三個整數 fa,lch,rch,表示 fa 的左兒子爲 lch,右兒子爲 rch。(如果 lch 爲 0 則表示 fa 沒有左兒子,rch同理)
最後一行爲節點 o1 和 o2。
輸出描述:
輸出一個整數表示答案。
示例1:
輸入
7 1
1 2 3
2 4 5
4 0 0
5 0 0
3 6 7
6 0 0
7 0 0
輸出
5
分析以某個節點爲根節點的最大距離爲左子樹的最大高度+右子樹的最大高度+1,不斷遞歸,更新最大值。
import java.util.*;
public class Main{
public static int res=0;
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
int number=scanner.nextInt();
int root=scanner.nextInt();
int arr[][]=new int[number+1][2];
for(int i=1;i<=number;i++){
int p=scanner.nextInt();
arr[p][0]=scanner.nextInt();
arr[p][1]=scanner.nextInt();
}
countLevel(arr,root);
System.out.println(res);
}
public static int countLevel(int[][] arr,int node){
if(node==0){
return 0;
}
if(arr[node][0]==0&&arr[node][1]==0){
return 1;
}
int left = countLevel(arr,arr[node][0]);
int right = countLevel(arr,arr[node][1]);
int path=left+right+1;
res=Math.max(res,path);
return 1+Math.max(left,right);
}
}