2021-10-25

JZ26 树的子结构

题目地址
描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
示例1

输入:
{8,8,#,9,#,2,#,5},{8,9,#,2}
返回值:
true

解题思路
遍历树A,每当遍历到的结点的值==树B根节点的值,就从当前相等结点遍历,判断从相等结点开始往后时候相等。
如图,遍历到A树的第二层最左边结点,但是从该结点往后并不与B树相同,继续遍历A树。
在这里插入图片描述
继续遍历
在这里插入图片描述
代码

import java.util.*;
/**
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) {
        //判断root2是否是root1的子结构
        if(root2==null || root1==null){//不要忘记判断root1是否为空
            return false;
        }
        //遍历root1,找到root1中结点和root2根节点值相同的结点
        //此处采用层次遍历
        Queue<TreeNode> q=new LinkedList<>();
        q.add(root1);
        TreeNode tmp=null;
        while(!q.isEmpty()){
            tmp=q.poll();
            if(tmp.val==root2.val && isSame(tmp,root2)){
                return true;
            }
            if(tmp.left!=null){
                q.add(tmp.left);
            }
            if(tmp.right!=null){
                q.add(tmp.right);
            }
        }
        return false;
    }
    public boolean isSame(TreeNode root1,TreeNode root2){
        if(root2==null){
            return true;
        }else if(root1==null){//root1为空  且  root2不为空
            return false;
        }
        //root1,root2都不为空
        if(root1.val!=root2.val){
            return false;
        }
        return isSame(root1.left,root2.left)&&isSame(root1.right,root2.right);
    }
}

JZ32 从上往下打印二叉树

题目地址
描述
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
示例1

输入:
{5,4,#,3,#,2,#,1}
返回值:
[5,4,3,2,1]

代码
简单的树的层次遍历,采用队列。

import java.util.*;
/**
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> res=new ArrayList<>();
        if(root==null){
            return res;
        }
        Queue<TreeNode> q=new LinkedList<>();
        q.add(root);
        TreeNode tmp=null;
        while(!q.isEmpty()){
            tmp=q.poll();
            res.add(tmp.val);
            if(tmp.left!=null){
                q.add(tmp.left);
            }
            if(tmp.right!=null){
                q.add(tmp.right);
            }
        }
        return res;
    }
}

JZ33 二叉搜索树的后序遍历序列

题目地址
描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。(ps:我们约定空树不是二叉搜索树)
示例1

输入:
[4,8,6,12,16,14,10]
返回值:
true

解题思路
1.二叉搜索树的后序遍历:左子树->右子树->根节点
2.对于如下搜索二叉树
二叉树
该搜索二叉树后序遍历序列[2,5,4,7,9,6]。
可以看出6是头结点,可以根据6将后序序列分为左右两部分,左边<根节点值,右边>根节点值。即{2,5,4}<6 and 6>{7,9,6}。
根据此原理判断子树{2,5,4}和{7,9,6}。
代码

public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {
        if(sequence==null || sequence.length==0){
            return false;
        }
        return Verify(sequence,0,sequence.length-1);
    }
    public boolean Verify(int[] sequence,int l,int r){
        if(l>=r){
            return true;
        }
        int root=sequence[r];
        //划分左子树   左子树结点都小于根节点
        int par=l;
        while(par < r && sequence[par]<root){par++;}//切勿写成while(par++ < r && sequence[par]<root){}
        //判断右子树结点是否都小于根节点
        for(int i=par;i<r;i++){
            if(sequence[i]<root){
                return false;
            }
        }
        return Verify(sequence,l,par-1)&&Verify(sequence,par,r-1);
    }
}

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

题目地址
描述
输入一颗二叉树的根节点root和一个整数expectNumber,找出二叉树中结点值的和为expectNumber的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
如二叉树root为{10,5,12,4,7},expectNumber为22
在这里插入图片描述
则合法路径有[[10,5,7],[10,12]]

数据范围:
树中节点总数在范围 [0, 5000] 内
-1000 <= 节点值 <= 1000
-1000 <= expectNumber <= 1000

示例1

输入:
{10,5,12,4,7},22
返回值:
[[10,5,7],[10,12]]
说明:
返回[[10,12],[10,5,7]]也是对的 

示例2

输入:
{10,5,12,4,7},15
返回值:
[]

示例3

输入:
{5,4,8,11,#,13,4,7,2,#,#,5,1},22
返回值:
[[5,4,11,2],[5,8,4,5]]

代码
解题思路:采用深度优先搜索方式,枚举每一条从根节点到叶子节点的路径。当遍历到叶子节点时,如果此时路径和等于目标时,就找到一条满足条件的路径了。

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 {
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int expectNumber) {
        ArrayList<ArrayList<Integer>> res=new ArrayList<>();
        if(root==null){
            return res;
        }
        ArrayList<Integer> nowList=new ArrayList<Integer>();
        dfs(root,expectNumber,0,nowList,res);
        return res;
    }
    public void dfs(TreeNode now,int expectNumber,int num,ArrayList<Integer> nowList,ArrayList<ArrayList<Integer>> res){
        if(now.left==null && now.right==null){
            if(num+now.val==expectNumber){
                nowList.add(now.val);
                //注意,ArrayList的add方法是浅拷贝,只拷贝引用,此处需要采用深拷贝的形式
                res.add(new ArrayList<>(nowList));
                nowList.remove(nowList.size()-1);
            }
            return;
        }
        nowList.add(now.val);
        if(now.left!=null){
            dfs(now.left,expectNumber,num+now.val,nowList,res);
        }
        if(now.right!=null){
            dfs(now.right,expectNumber,num+now.val,nowList,res);
        }
        nowList.remove(nowList.size()-1);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值