首页 > 编程语言 >每日算法之树的子结构

每日算法之树的子结构

时间:2022-12-03 10:56:15浏览次数:57  
标签:return 算法 子结构 之树 TreeNode null root1 节点 root2

JZ26 树的子结构

描述

输入两棵二叉树A,B,判断B是不是A的子结构。(我们约定空树不是任意一个树的子结构)
假如给定A为{8,8,7,9,2,#,#,#,#,4,7},B为{8,9,2},2个树的结构如下,可以看出B是A的子结构

题解1 深度遍历

思路

既然是要找到A树中是否有B树这样子树,如果是有子树肯定是要遍历这个子树和B树,将两个的节点一一比较,但是这样的子树不一定就是A树根节点开始的,所以我们还要先找到子树可能出现的位置。
既然是可能的位置,那我们可以对A树的每个节点前序递归遍历,寻找是否有这样的子树,而寻找是否有子树的时候,我们就将A树与B树同步前序遍历,依次比较节点值。

具体做法:
step 1:因为空树不是任何树的子树,所以要先判断B树是否为空树。
step 2:当A树为空节点,但是B树还有节点的时候,不为子树,但是A树不为空节点,B树为空节点时可以是子树。
step 3:每次递归比较A树从当前节点开始,是否与B树完全一致,同步前序遍历。
step 4:A树自己再前序遍历进入子节点,当作子树起点再与B树同步遍历。
step 5:以上情况任意只要有一种即可。

代码

public class Solution {
    public boolean HasSubtree(TreeNode root1, TreeNode root2) {
        if (root2 == null) return false;
        //一个节点为空 一节点不为空
        if (root1 == null) return false;

        boolean flag1 = recursion(root1, root2);

        boolean flag2 = HasSubtree(root1.left, root2);

        boolean flag3 = HasSubtree(root1.right, root2);
        return flag1 || flag2 || flag3;
    }

    // 判断是否有相等的根节点
    public boolean recursion(TreeNode root1, TreeNode root2) {
        //一个节点为空 一节点不为空
        if (root1 == null && root2 != null) return false;

        if (root1 == null || root2 == null) return true;

        if (root1.val != root2.val) return false;

        return recursion(root1.left, root2.left) && recursion(root1.right, root2.right);
    }
}

题解2 广度遍历

思路

首先对于A树层次遍历每一个节点,遇到一个与B树根节点相同的节点,我们就开始同步层次遍历比较以这个节点为根的树中是否出现了B树的全部节点。因为我们只考虑B树的所有节点是否在A树中全部出现,那我们就以B树为基,再进行一次层次遍历,A树从那个节点开始跟随B树一致进行层次遍历就行了,比较对应的每个点是否相同,或者B树是否有超出A树没有的节点。

具体做法:

step 1:先判断空树,空树不为子结构。
step 2:利用队列辅助,层次遍历第一棵树,每次检查遍历到的节点是否和第二棵树的根节点相同。
step 3:若是相同,可以以该节点为子树根节点,再次借助队列辅助,同步层次遍历这个子树与第二棵树,这个时候以第二棵树为基,只要找到第二棵树的全部节点,就算找到了子结构。

代码

package mid.JZ26树的子结构;
import java.util.LinkedList;

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 (root2 == null) return false;
        //一个节点为空 一节点不为空
        if (root1 == null) return false;
        LinkedList<TreeNode> q = new LinkedList<>();
        q.offer(root1);

        while (!q.isEmpty()) {
            TreeNode node = q.poll();
            if (node.val == root2.val) {
                if (helper(node, root2)) {
                    return true;
                }
            }

            if (node.left != null) q.offer(node.left);
            if (node.right != null) q.offer(node.right);
        }
        return false;
    }

    public boolean helper(TreeNode root1, TreeNode root2) {
        LinkedList<TreeNode> q1 = new LinkedList<>();
        LinkedList<TreeNode> q2 = new LinkedList<>();
        q1.offer(root1);
        q2.offer(root2);

        while (!q2.isEmpty()) {
            TreeNode node1 = q1.poll();
            TreeNode node2 = q2.poll();
            //树1为空或者二者不相等
            if (node1 == null || node1.val != node2.val)
                return false;
            //树2还有左子树
            if (node2.left != null) {
                //子树入队
                q1.offer(node1.left);
                q2.offer(node2.left);
            }
            //树2还有右子树
            if (node2.right != null) {
                //子树入队
                q1.offer(node1.right);
                q2.offer(node2.right);
            }
        }
        return true;
    }

}


// 深度遍历查询
/*public class Solution {
    public boolean HasSubtree(TreeNode root1, TreeNode root2) {
        if (root2 == null) return false;
        //一个节点为空 一节点不为空
        if (root1 == null) return false;

        boolean flag1 = recursion(root1, root2);

        boolean flag2 = HasSubtree(root1.left, root2);

        boolean flag3 = HasSubtree(root1.right, root2);
        return flag1 || flag2 || flag3;
    }

    // 判断是否有相等的根节点
    public boolean recursion(TreeNode root1, TreeNode root2) {
        //一个节点为空 一节点不为空
        if (root1 == null && root2 != null) return false;

        if (root1 == null || root2 == null) return true;

        if (root1.val != root2.val) return false;

        return recursion(root1.left, root2.left) && recursion(root1.right, root2.right);
    }
}*/

标签:return,算法,子结构,之树,TreeNode,null,root1,节点,root2
From: https://www.cnblogs.com/loongnuts/p/16947136.html

相关文章

  • AI入门之搜索算法
    启发式搜索(有信息式搜索)以寻找最短路径问题为例设一个评估函数f(n),从当前节点出发,根据评价函数来选择后续节点设置一个启发性函数h(n),计算从节点n到目标节点之间所......
  • 蓝桥杯 ALGO-50算法训练 数组查找及替换
    问题描述给定某整数数组和某一整数b。要求删除数组中可以被b整除的所有元素,同时将该数组各元素按从小到大排序。如果数组元素数值在A到Z的ASCII之间,替换为对应字母。......
  • 蓝桥杯算法学习整理
    报名了蓝桥杯,但是对于算法的基础却不是很好,收集了一些学习的链接,以下链接都是转载自别人名下的博客文章,如果博主介意的话,请通知我立即删除。供日后复习时使用:前部分是摘......
  • 蓝桥杯 ALGO-47算法训练 蜜蜂飞舞
    时间限制:1.0s内存限制:512.0MB问题描述“两只小蜜蜂呀,飞在花丛中呀……”话说这天天上飞舞着两只蜜蜂,它们在跳一种奇怪的舞蹈。用一个空间直角坐标系来描述这个......
  • 蓝桥杯 ALGO-54算法训练 简单加法(基本型)
    时间限制:1.0s内存限制:512.0MB问题描述首先给出简单加法算式的定义:如果有一个算式(i)+(i+1)+(i+2),(i>=0),在计算的过程中,没有任何一个数位出现了进位,则称其为......
  • 蓝桥杯 ALGO-57算法训练 删除多余括号
    时间限制:1.0s内存限制:512.0MB问题描述从键盘输入一个含有括号的四则运算表达式,要求去掉可能含有的多余的括号,结果要保持原表达式中变量和运算符的相对位置不变,且与......
  • golang的插入排序算法
    1、什么是插入排序?先看一个例子:{7,6,1,9,3}无序数列中,我们约定好无序数列的第一个元素7作为有序数列{7},然后分别对{6,1,9,3}的数与7进行比较移位得到新的有序数列。第一次迭......
  • 【算法】用面向对象的方法求出数组中重复 value的个数,按如下个数输出:
    1出现:1次3出现:2次8出现:3次2出现:4次int[]arr={1,4,1,4,2,5,4,5,8,7,8,77,88,5,4,9,6,2,4,1,5};今天看一个关于基础资料的文档,里面有这么一道算法题。刚开始看了一下,只......
  • 算法记录--好多内容也是借鉴大神的
    1、链表翻转/*publicclassListNode{intval;ListNodenext=null;ListNode(intval){this.val=val;}}*/publicclassSolutio......
  • Python中mro继承顺序查询之C3算法
    1.mro遍历顺序1. python中存在多继承:A同时继承B和C,B继承E,C继承F,E和F最终继承object,如果我们访问A的实例对象的属性,他的查找方法遵循C3算法,(之前是深度优先查询,一条路......