手撕算法——二叉树面试题目汇总

二叉树遍历

先序遍历

递归
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);
	}
}

二叉树中和为某一值的路径

面试题34.二叉树中和为某一值的路径

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);
    }
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值