0
点赞
收藏
分享

微信扫一扫

26. 树的子结构


链接

​​​https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof/​​

难度: #中等

题目

输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)

B是A的子结构, 即 A中有出现和B相同的结构和节点值。

例如:

给定的树 A:

3
/ \
4 5
/ \
1 2

给定的树 B:

4 
/
1

返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。

示例 1:

输入:A = [1,2,3], B = [3,1]
输出:false

示例 2:

输入:A = [3,4,5,1,2], B = [4,1]
输出:true

限制:​0 <= 节点个数 <= 10000​

代码框架

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {

}
}

题目解析


26. 树的子结构_二叉树


1.创建一个辅助函数判断两棵树是否相等

2.递归遍历A树的每一个节点作为根结点和B树进行比较

3.每次遇到A的节点与B的头结点相同,则继续比较A和B的子节点

解答思路1:

在二叉树A中先序遍历,

找到第一个和B的第一个相同的节点,

然后比较其左右子节点是否相同,

如果B没有左或者右节点,则无需比较,

直接返回true,

如果A没有子节点,B有子节点,则一定不是,

直接返回false。

解答思路2:

解答思路1的代码优化写法,

利用了&&和||逻辑运算符的快速返回特性,

在二叉树A中先序遍历,

找到第一个和B的第一个相同的节点,

然后比较其左右子节点是否相同,

如果B没有左或者有节点,则无需比较。

测试用例

package edu.yuwen.sowrd.num26.solution;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import edu.yuwen.sowrd.entity.TreeNode;
import edu.yuwen.sowrd.num26.sol1.Solution;

public class SolutionTest {

/**
* 示例 1:
* 输入:A = [1,2,3], B = [3,1]
* 输出:false
*/
@Test
public void testCase1() {
Solution solution = new Solution();
TreeNode a = getTreeNodeA1();
TreeNode b = getTreeNodeB1();
boolean res = solution.isSubStructure(a, b);
Assertions.assertEquals(false, res);
}

/**
* 示例 2:
* 输入:A = [3,4,5,1,2], B = [4,1]
* 输出:true
*/
@Test
public void testCase2() {
Solution solution = new Solution();
TreeNode a = getTreeNodeA2();
TreeNode b = getTreeNodeB2();
boolean res = solution.isSubStructure(a, b);
Assertions.assertEquals(true, res);
}

/**
* 1
* / \
* 2 3
*/
public TreeNode getTreeNodeA1() {
TreeNode node1 = new TreeNode(1);
TreeNode node2 = new TreeNode(2);
TreeNode node3 = new TreeNode(3);

node1.left = node2;
node1.right = node3;

return node1;
}

/**
* 3
* /
* 1
*/
public TreeNode getTreeNodeB1() {
TreeNode node1 = new TreeNode(3);
TreeNode node2 = new TreeNode(1);

node1.left = node2;
return node1;
}

/**
* 3
* / \
* 4 5
* / \
* 1 2
*/
public TreeNode getTreeNodeA2() {
TreeNode node1 = new TreeNode(3);
TreeNode node2 = new TreeNode(4);
TreeNode node3 = new TreeNode(5);
TreeNode node4 = new TreeNode(1);
TreeNode node5 = new TreeNode(2);

node1.left = node2;
node1.right = node3;

node2.left = node4;
node2.right = node5;

return node1;
}

/**
* 4
* /
* 1
*/
public TreeNode getTreeNodeB2() {
TreeNode node1 = new TreeNode(4);
TreeNode node2 = new TreeNode(1);

node1.left = node2;
return node1;
}
}

解答1

package edu.yuwen.sowrd.num26.sol1;

import edu.yuwen.sowrd.entity.TreeNode;

public class Solution {
public boolean isSubStructure(TreeNode a, TreeNode b) {
if (a == null || b == null) {
return false;
}

// 比较当前节点及其子节点
boolean cur = compare(a, b);
// 确定是子结构即可返回
if (cur) {
return true;
}

// 否则遍历左右子树
if (a.left != null) {
boolean left = isSubStructure(a.left, b);
// 只要相等了,即可返回
if (left) {
return true;
}
}

if (a.right != null) {
boolean right = isSubStructure(a.right, b);
if (right) {
return true;
}
}

return false;
}

// 比较两颗二叉树是否相同
private boolean compare(TreeNode a, TreeNode b) {
// base case
if (a == null) {
if (b == null) {
return true;
}
return false;
}

if (a != null && b == null) {
return true;
}

// 比较当前值
boolean cur = a.val == b.val;
// 只要有一个节点不同,即可返回
if (!cur) {
return false;
}

// 比较左节点
boolean left = compare(a.left, b.left);
if (!left) {
return false;
}

// 比较右节点
boolean right = compare(a.right, b.right);
if (!right) {
return false;
}

// 当前和左右节点都相同,才认为相同
return true;
}
}

解答2 推荐

package edu.yuwen.sowrd.num26.sol2;

import edu.yuwen.sowrd.entity.TreeNode;

public class Solution {
public boolean isSubStructure(TreeNode a, TreeNode b) {
if (a == null || b == null) {
return false;
}

// 先序遍历二叉树A, 比较当前节点及其子节点
// 确定是子结构即可返回
// 否则遍历二叉树a下一个节点
return compare(a, b) || isSubStructure(a.left, b)
|| isSubStructure(a.right, b);
}

// 比较两颗二叉树是否相同
private boolean compare(TreeNode a, TreeNode b) {
// base case
// b为null,则一定相同
if (b == null) {
return true;
}
// b不为null,但a为null,则一定不同
else if (a == null) {
return false;
}

// 比较当前值, 比较左节点,比较右节点
// 当前和左右节点都相同,才认为相同
// 否则只要有一个节点不同,即可返回
return a.val == b.val && compare(a.left, b.left)
&& compare(a.right, b.right);
}
}


举报

相关推荐

0 条评论