二叉树遍历
先序遍历
递归
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);
}
}