数据结构与算法之二叉树: 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)