数据结构与算法之二叉树: LeetCode 100. 相同的树 (Typescript版)

相同的树

  • https://leetcode.cn/problems/same-tree/

描述

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

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

示例 1

  1         1
 /  \      /  \  
2    3    2    3   
输入:p = [1,2,3], q = [1,2,3]
输出:true

示例 2

  1      1
 /        \  
2          2
输入:p = [1,2], q = [1,null,2]
输出:false

示例 3

  1         1
 /  \      /  \  
2    1    1    2
输入:p = [1,2,1], q = [1,1,2]
输出:false

提示

  • 两棵树上的节点数目都在范围 [0, 100] 内
  • - 1 0 4 10^4 104 <= Node.val <= 1 0 4 10^4 104

算法实现

1 )深度优先递归版本

/**
 * 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 && !q) return true;
    // 不相同时
    if (p?.val !== q?.val) return false;
    // 递归判断
    return isSameTree(p?.left, q?.left) && isSameTree(p?.right, q?.right);
};
  • 解题思路
    • 两棵树相同:根节点值相同,左子树相同,右子树相同
    • 如此一来,我们把若干大问题,分解成若干个相似小问题
    • 符合:分、解、合特性
    • 选择分而治之
  • 解题步骤
    • 分:获取两个树的左子树和右子树
    • 解:递归地判断两个树的左子树是否相同,右子树是否相同
    • 合:将上述结果合并,若根节点值也相同,树就相同
  • 时间复杂度:O(n)
    • n是所有节点数
  • 空间复杂度:O(n)
    • 递归,底部形成堆栈
    • n是树的节点数,最坏情况下,树的节点数是树的高度

2 )广度优先迭代版本

/**
 * 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 && !q) return true;
    // 不相同时
    if (p?.val !== q?.val) return false;
    // 声明两个队列
    const queue1 = [p];
    const queue2 = [q];
    // 迭代对比
    while (queue1.length && queue2.length) {
        // 拿到队首
        const pTop = queue1.shift();
        const qTop = queue2.shift();
        // 对比判断, 符合则提前终止
        if (pTop.val !== qTop.val) return false;
        // 拿到下一层
        const pLeft = pTop?.left;
        const pRight = pTop?.right;
        const qLeft = qTop?.left;
        const qRight = qTop?.right;
        // 进入判断, 符合则提前终止
        if ((pLeft && !qLeft) || (!pLeft && qLeft)) return false;
        if ((pRight && !qRight) || (!pRight && qRight)) return false;
        // 进入队列
        if (pLeft) queue1.push(pLeft);
        if (pRight) queue1.push(pRight);
        if (qLeft) queue2.push(qLeft);
        if (qRight) queue2.push(qRight);
    }
    // 最终结果对比
    return !queue1.length && !queue2.length;
}
  • 这里换一种广度优先遍历来对比两棵树是否相同
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

你可能感兴趣的:(Data,Structure,and,Algorithms,leetcode,算法,二叉树)