返回介绍

solution / 0100-0199 / 0100.Same Tree / README

发布于 2024-06-17 01:04:05 字数 15314 浏览 0 评论 0 收藏 0

100. 相同的树

English Version

题目描述

给你两棵二叉树的根节点 pq ,编写一个函数来检验这两棵树是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

 

示例 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

解法

方法一:DFS

我们可以使用 DFS 递归的方法来解决这个问题。

首先判断两个二叉树的根节点是否相同,如果两个根节点都为空,则两个二叉树相同,如果两个根节点中有且只有一个为空,则两个二叉树一定不同。如果两个根节点都不为空,则判断它们的值是否相同,如果不相同则两个二叉树一定不同,如果相同,则分别判断两个二叉树的左子树是否相同以及右子树是否相同。当以上所有条件都满足时,两个二叉树才相同。

时间复杂度 $O(\min(m, n))$,空间复杂度 $O(\min(m, n))$。其中 $m$ 和 $n$ 分别是两个二叉树的节点个数。空间复杂度主要取决于递归调用的层数,递归调用的层数不会超过较小的二叉树的节点个数。

# Definition for a binary tree node.
# class TreeNode:
#   def __init__(self, val=0, left=None, right=None):
#     self.val = val
#     self.left = left
#     self.right = right
class Solution:
  def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
    if p == q:
      return True
    if p is None or q is None or p.val != q.val:
      return False
    return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
/**
 * 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 == q) return true;
    if (p == null || q == null || p.val != q.val) return false;
    return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
  }
}
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *   int val;
 *   TreeNode *left;
 *   TreeNode *right;
 *   TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *   TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *   TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
  bool isSameTree(TreeNode* p, TreeNode* q) {
    if (p == q) return true;
    if (!p || !q || p->val != q->val) return false;
    return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
  }
};
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *   Val int
 *   Left *TreeNode
 *   Right *TreeNode
 * }
 */
func isSameTree(p *TreeNode, q *TreeNode) bool {
  if p == q {
    return true
  }
  if p == nil || q == nil || p.Val != q.Val {
    return false
  }
  return isSameTree(p.Left, q.Left) && isSameTree(p.Right, q.Right)
}
/**
 * Definition for a binary tree node.
 * class TreeNode {
 *   val: number
 *   left: TreeNode | null
 *   right: TreeNode | null
 *   constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 *   }
 * }
 */

function isSameTree(p: TreeNode | null, q: TreeNode | null): boolean {
  if (p == null && q == null) {
    return true;
  }
  if (p == null || q == null || p.val !== q.val) {
    return false;
  }
  return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
// Definition for a binary tree node.
// #[derive(Debug, PartialEq, Eq)]
// pub struct TreeNode {
//   pub val: i32,
//   pub left: Option<Rc<RefCell<TreeNode>>>,
//   pub right: Option<Rc<RefCell<TreeNode>>>,
// }
//
// impl TreeNode {
//   #[inline]
//   pub fn new(val: i32) -> Self {
//   TreeNode {
//     val,
//     left: None,
//     right: None
//   }
//   }
// }
use std::rc::Rc;
use std::cell::RefCell;
impl Solution {
  fn dfs(p: &Option<Rc<RefCell<TreeNode>>>, q: &Option<Rc<RefCell<TreeNode>>>) -> bool {
    if p.is_none() && q.is_none() {
      return true;
    }
    if p.is_none() || q.is_none() {
      return false;
    }
    let r1 = p.as_ref().unwrap().borrow();
    let r2 = q.as_ref().unwrap().borrow();
    r1.val == r2.val && Self::dfs(&r1.left, &r2.left) && Self::dfs(&r1.right, &r2.right)
  }

  pub fn is_same_tree(
    p: Option<Rc<RefCell<TreeNode>>>,
    q: Option<Rc<RefCell<TreeNode>>>
  ) -> bool {
    Self::dfs(&p, &q)
  }
}
/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *   this.val = (val===undefined ? 0 : val)
 *   this.left = (left===undefined ? null : left)
 *   this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} p
 * @param {TreeNode} q
 * @return {boolean}
 */
var isSameTree = function (p, q) {
  if (!p && !q) return true;
  if (p && q) {
    return p.val === q.val && isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
  }
  return false;
};
/**
 * Definition for a binary tree node.
 * class TreeNode {
 *   public $val = null;
 *   public $left = null;
 *   public $right = null;
 *   function __construct($val = 0, $left = null, $right = null) {
 *     $this->val = $val;
 *     $this->left = $left;
 *     $this->right = $right;
 *   }
 * }
 */
class Solution {
  /**
   * @param TreeNode $p
   * @param TreeNode $q
   * @return Boolean
   */
  function isSameTree($p, $q) {
    if ($p == null && $q == null) {
      return true;
    }
    if ($p == null || $q == null) {
      return false;
    }
    if ($p->val != $q->val) {
      return false;
    }
    return $this->isSameTree($p->left, $q->left) && $this->isSameTree($p->right, $q->right);
  }
}

方法二:BFS

我们也可以使用 BFS 迭代的方法来解决这个问题。

首先将两个二叉树的根节点分别加入两个队列。每次从两个队列各取出一个节点,进行如下比较操作。如果两个节点的值不相同,则两个二叉树的结构一定不同,如果两个节点的值相同,则判断两个节点的子节点是否为空,如果只有一个节点的左子节点为空,则两个二叉树的结构一定不同,如果只有一个节点的右子节点为空,则两个二叉树的结构一定不同,如果左右子节点的结构相同,则将两个节点的左子节点和右子节点分别加入两个队列,对于下一次迭代,将从两个队列各取出一个节点进行比较。当两个队列同时为空时,说明我们已经比较完了所有节点,两个二叉树的结构完全相同。

时间复杂度 $O(\min(m, n))$,空间复杂度 $O(\min(m, n))$。其中 $m$ 和 $n$ 分别是两个二叉树的节点个数。空间复杂度主要取决于队列中的元素个数,队列中的元素个数不会超过较小的二叉树的节点个数。

# Definition for a binary tree node.
# class TreeNode:
#   def __init__(self, val=0, left=None, right=None):
#     self.val = val
#     self.left = left
#     self.right = right
class Solution:
  def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
    if p == q:
      return True
    if p is None or q is None:
      return False
    q1, q2 = deque([p]), deque([q])
    while q1 and q2:
      a, b = q1.popleft(), q2.popleft()
      if a.val != b.val:
        return False
      la, ra = a.left, a.right
      lb, rb = b.left, b.right
      if (la and not lb) or (lb and not la):
        return False
      if (ra and not rb) or (rb and not ra):
        return False
      if la:
        q1.append(la)
        q2.append(lb)
      if ra:
        q1.append(ra)
        q2.append(rb)
    return True
/**
 * 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 == q) {
      return true;
    }
    if (p == null || q == null) {
      return false;
    }
    Deque<TreeNode> q1 = new ArrayDeque<>();
    Deque<TreeNode> q2 = new ArrayDeque<>();
    q1.offer(p);
    q2.offer(q);
    while (!q1.isEmpty() && !q2.isEmpty()) {
      p = q1.poll();
      q = q2.poll();
      if (p.val != q.val) {
        return false;
      }
      TreeNode la = p.left, ra = p.right;
      TreeNode lb = q.left, rb = q.right;
      if ((la != null && lb == null) || (lb != null && la == null)) {
        return false;
      }
      if ((ra != null && rb == null) || (rb != null && ra == null)) {
        return false;
      }
      if (la != null) {
        q1.offer(la);
        q2.offer(lb);
      }
      if (ra != null) {
        q1.offer(ra);
        q2.offer(rb);
      }
    }
    return true;
  }
}
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *   int val;
 *   TreeNode *left;
 *   TreeNode *right;
 *   TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *   TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *   TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
  bool isSameTree(TreeNode* p, TreeNode* q) {
    if (p == q) return true;
    if (!p || !q) return false;
    queue<TreeNode*> q1{{p}};
    queue<TreeNode*> q2{{q}};
    while (!q1.empty() && !q2.empty()) {
      p = q1.front();
      q = q2.front();
      if (p->val != q->val) return false;
      q1.pop();
      q2.pop();
      TreeNode *la = p->left, *ra = p->right;
      TreeNode *lb = q->left, *rb = q->right;
      if ((la && !lb) || (lb && !la)) return false;
      if ((ra && !rb) || (rb && !ra)) return false;
      if (la) {
        q1.push(la);
        q2.push(lb);
      }
      if (ra) {
        q1.push(ra);
        q2.push(rb);
      }
    }
    return true;
  }
};
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *   Val int
 *   Left *TreeNode
 *   Right *TreeNode
 * }
 */
func isSameTree(p *TreeNode, q *TreeNode) bool {
  if p == q {
    return true
  }
  if p == nil || q == nil {
    return false
  }
  q1 := []*TreeNode{p}
  q2 := []*TreeNode{q}
  for len(q1) > 0 && len(q2) > 0 {
    p, q = q1[0], q2[0]
    if p.Val != q.Val {
      return false
    }
    q1, q2 = q1[1:], q2[1:]
    la, ra := p.Left, p.Right
    lb, rb := q.Left, q.Right
    if (la != nil && lb == nil) || (lb != nil && la == nil) {
      return false
    }
    if (ra != nil && rb == nil) || (rb != nil && ra == nil) {
      return false
    }
    if la != nil {
      q1 = append(q1, la)
      q2 = append(q2, lb)
    }
    if ra != nil {
      q1 = append(q1, ra)
      q2 = append(q2, rb)
    }
  }
  return true
}
/**
 * Definition for a binary tree node.
 * class TreeNode {
 *   val: number
 *   left: TreeNode | null
 *   right: TreeNode | null
 *   constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 *   }
 * }
 */

function isSameTree(p: TreeNode | null, q: TreeNode | null): boolean {
  const queue = [];
  p && queue.push(p);
  q && queue.push(q);
  if (queue.length === 1) {
    return false;
  }
  while (queue.length !== 0) {
    const node1 = queue.shift();
    const node2 = queue.shift();
    if (node1.val !== node2.val) {
      return false;
    }
    if (
      (node1.left == null && node2.left != null) ||
      (node1.left != null && node2.left == null)
    ) {
      return false;
    }
    if (
      (node1.right == null && node2.right != null) ||
      (node1.right != null && node2.right == null)
    ) {
      return false;
    }

    if (node1.left != null) {
      queue.push(node1.left);
      queue.push(node2.left);
    }
    if (node1.right != null) {
      queue.push(node1.right);
      queue.push(node2.right);
    }
  }
  return true;
}
// Definition for a binary tree node.
// #[derive(Debug, PartialEq, Eq)]
// pub struct TreeNode {
//   pub val: i32,
//   pub left: Option<Rc<RefCell<TreeNode>>>,
//   pub right: Option<Rc<RefCell<TreeNode>>>,
// }
//
// impl TreeNode {
//   #[inline]
//   pub fn new(val: i32) -> Self {
//   TreeNode {
//     val,
//     left: None,
//     right: None
//   }
//   }
// }
use std::rc::Rc;
use std::cell::RefCell;
use std::collections::VecDeque;
impl Solution {
  pub fn is_same_tree(
    mut p: Option<Rc<RefCell<TreeNode>>>,
    mut q: Option<Rc<RefCell<TreeNode>>>
  ) -> bool {
    let mut queue = VecDeque::new();
    if p.is_some() {
      queue.push_back(p.take());
    }
    if q.is_some() {
      queue.push_back(q.take());
    }
    if queue.len() == 1 {
      return false;
    }
    while queue.len() != 0 {
      if let (Some(mut node1), Some(mut node2)) = (queue.pop_front(), queue.pop_front()) {
        let mut node1 = node1.as_mut().unwrap().borrow_mut();
        let mut node2 = node2.as_mut().unwrap().borrow_mut();
        if node1.val != node2.val {
          return false;
        }
        match (node1.left.is_some(), node2.left.is_some()) {
          (false, false) => {}
          (true, true) => {
            queue.push_back(node1.left.take());
            queue.push_back(node2.left.take());
          }
          (_, _) => {
            return false;
          }
        }
        match (node1.right.is_some(), node2.right.is_some()) {
          (false, false) => {}
          (true, true) => {
            queue.push_back(node1.right.take());
            queue.push_back(node2.right.take());
          }
          (_, _) => {
            return false;
          }
        }
      }
    }
    true
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文