Leetcode 100. 相同的树
❤️来自专栏《LeetCode基础算法题》 欢迎订阅❤️
关于作者
- 作者介绍
🍓 博客主页:作者主页 🍓 简介:JAVA领域优质创作者🥇、一名在校大三学生🎓、在校期间参加各种省赛、国赛,斩获一系列荣誉🏆。 🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨💻。
1、题目📑
给你两棵二叉树的根节点 p
和 q
,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
实例1:
输入:p = [1,2,3], q = [1,2,3] 输出:true
实例2:
输入:p = [1,2], q = [1,null,2] 输出:false
实例3:
输入:p = [1,2,1], q = [1,1,2] 输出:false
限制:
- 两棵树上的节点数目都在范围
[0, 100]
内 -104 <= Node.val <= 104
2、思路🧠
方法一:递归
特殊处理,优先比较两个根节点
-
如果两节点都为空,则返回 true;
-
如果两节点中有一个为空,则返回 false;
-
如果两节点值相同,则返回
isSameTree(p.left,q.left) && isSameTree(p.right, q.right)
比较左子树和右子树是否相同,进入了递归 -
其余情况一律为 false;
废话少说~~~~~上代码!
3、代码👨💻
第一次commit AC
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p == null && q == null) {
return true;
}
else if(p == null || q == null) {
return false;
}
else if(p.val == q.val) {
return isSameTree(p.left,q.left) && isSameTree(p.right, q.right);
}
return false;
}
}
时间复杂度:O( Min(m,n) ),m
和 n
分别是两个树的节点数
空间复杂度:O( Min(h1,h2) ),h1
, h2
表示两树高度
4、总结
该题目需要对树的结构以及遍历的理解,并且需要熟练的掌握递归才能顺利完成题目要求。
树的先序、中序、后序模板:
package com.cz.Tree;
import java.util.Stack;
/**
* @ProjectName: Data_structure
* @Package: com.cz.Tree
* @ClassName: UnRecursiveTraversalTree
* @Author: 张晟睿
* @Date: 2022/3/20 16:06
* @Version: 1.0
*/
public class UnRecursiveTraversalTree {
public static void main(String[] args) {
Node1 head = new Node1(1);
head.left = new Node1(2);
head.right = new Node1(3);
head.left.left = new Node1(4);
head.left.right = new Node1(5);
head.right.left = new Node1(6);
head.right.right = new Node1(7);
pre(head);
System.out.println("========");
middle(head);
System.out.println("========");
post(head);
System.out.println("========");
}
public static class Node1 {
public int value;
public Node1 left;
public Node1 right;
public Node1(int val) {
value = val;
}
}
public static void pre(Node1 head) {
System.out.println("先序遍历:");
Stack<Node1> s = new Stack<>();
if(head != null) {
s.push(head);
while(!s.isEmpty()) {
Node1 node = s.pop();
System.out.print(node.value + " ");
if(node.right != null) s.push(node.right);
if(node.left != null) s.push(node.left);
}
}
System.out.println();
}
public static void middle(Node1 head){
System.out.println("中序遍历:");
if (head != null) {
Stack<Node1> s = new Stack<>();
while(!s.isEmpty() || head != null) {
//步骤1:如果头结点不为空的话,一直向左边执行
if (head != null) {
s.push(head);
head = head.left;
}else {//根节点打印后,来到右树,继续执行步骤1
head = s.pop();
System.out.print(head.value + " ");
head = head.right;
}
}
System.out.println();
}
}
public static void post(Node1 head){
System.out.println("后序遍历:");
if(head != null) {
Stack<Node1> s = new Stack<>();
s.push(head);
Node1 c = null; //指向栈顶的某个元素的位置
while(!s.isEmpty()) {
c = s.peek();
//判断c左孩子 是否已经处理过
if(c.left != null && head != c.left && head != c.right) {
s.push(c.left);
//判断c右孩子 是否已经处理过
}else if(c.right != null && head != c.right) {
s.push(c.right);
}else {
System.out.print(s.pop().value+" ");
head = c; //head用来记录上次打印的内容
}
}
System.out.println();
}
}
}