剑指offer第二版-26树的子结构

本文介绍了一种用于判断一棵二叉树是否为另一棵二叉树子结构的算法。通过递归方式,首先判断两树根节点是否相等,然后检查子树是否完全匹配。若根节点匹配失败,继续在当前节点的左右子树中寻找匹配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * 树的子结构
 * <p>
 * 输入两棵二叉树A和B,判断B是不是A的子结构。
 * <p>
 * 当A有一个节点与B的根节点值相同时,则需要从A的那个节点开始严格匹配,对应于下面的tree1HasTree2FromRoot函数。
 * 如果匹配不成功,则返回到开始匹配的那个节点,对它的左右子树继续判断是否与B的根节点值相同,重复上述过程。
 * 应注意,必须先比较root2的节点是否为空
 *
 * @author VicterTian
 * @version V1.0
 * @Date 2019/2/26
 */
public class P148_SubstructureInTree {
	static class TreeNode<T> {
		T val;
		TreeNode<T> left;
		TreeNode<T> right;

		TreeNode(T val) {
			this.left = null;
			this.right = null;
			this.val = val;
		}
	}

	private static boolean hasSubtree(TreeNode<Integer> root1, TreeNode<Integer> root2) {
		if (root2 == null) {
			return true;
		}
		if (root1 == null) {
			return false;
		}
		if (root1.val.equals(root2.val)) {
			if (tree1HasTree2FromRoot(root1, root2)) {
				return true;
			}
		}
		return hasSubtree(root1.left, root2) || hasSubtree(root1.right, root2);
	}

	private static boolean tree1HasTree2FromRoot(TreeNode<Integer> root1, TreeNode<Integer> root2) {
		if (root2 == null) {
			return true;
		}
		if (root1 == null) {
			return false;
		}

		return root1.val.equals(root2.val) && tree1HasTree2FromRoot(root1.left, root2.left) && tree1HasTree2FromRoot(root1.right, root2.right);
	}

	public static void main(String[] args) {
		TreeNode<Integer> root1 = new TreeNode<>(8);
		root1.left = new TreeNode<>(8);
		root1.right = new TreeNode<>(7);
		root1.left.left = new TreeNode<>(9);
		root1.left.right = new TreeNode<>(2);
		root1.left.right.left = new TreeNode<>(4);
		root1.left.right.right = new TreeNode<>(7);
		TreeNode<Integer> root2 = new TreeNode<>(8);
		root2.left = new TreeNode<>(9);
		root2.right = new TreeNode<>(2);
		TreeNode<Integer> root3 = new TreeNode<>(2);
		root3.left = new TreeNode<>(4);
		root3.right = new TreeNode<>(3);
		System.out.println(hasSubtree(root1, root2));
		System.out.println(hasSubtree(root1, root3));
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值