前言
最近研究二叉树,刚好做了两道二叉树的左右子树比较问题,发现问题思路和代码都比较相近啊。归类在这里总结一下,发现一下规律。
100. 相同的树
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/same-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
如下,代码非常少,这就是递归的魅力了。本题让我们比较两棵树是否相同。常用的两种思路:1、遍历两棵树,依次比较结构和值相同就相同。
本次用第二种思路更简单些,就是分解问题的思想:解决思路= 根节点相同(值相同或同为两棵空树)+左子树相同+ 右子树相同 对每一个节点都是这样,利用好返回值的问题的定义,写出如下代码:
递归退出条件:
- 两个当前节点同为空,true
- 只有一个为空,false
- 值不相等,false
/**
* 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 === null && q === null) return true
if(p === null || q === null) return false
if(p.val !== q.val) return false
return isSameTree(p.left,q.left) && isSameTree(p.right,q.right)
};
101.对称二叉树
给你一个二叉树的根节点 root , 检查它是否轴对称。
代码有些许差异,封装了一个函数,主要是因为退出条件涉及到左右子树。
思路和代码可以说及其的类似了,解决思路 = 从根节点开始(根为null则是空树,直接true)+(左子树的左子树 = 右子树的右子树)+ (左子树的右子树 = 右子树的左子树) 对每一个节点都是这样,利用好返回值的问题的定义,写出如下代码:
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isSymmetric = function(root) {
if(root === null) return true
const isSameTree = (left,right)=>{
if(left === null && right === null) return true
if(left === null || right === null) return false
if(left.val !== right.val) return false
return isSameTree(left.left,right.right) && isSameTree(left.right,right.left)
}
return isSameTree(root.left,root.right)
};
572. 另一棵树的子树
给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。
二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。
本题和100相同的树,及其类似,需要用到相同的树来判断二叉树中每一个节点是否有与目标子树相同的一颗子树。
所以我们选择遍历root,对每一个节点使用100题中的方法判断是否满足
主要是在后面加入的一段逻辑
对于每一个节点,当root为null,看sub的值即可,也是null就为true
判断一当前root为根,是否和sub结构数据都相同
没有则走递归去左右子树,只要有一个相同的就行
var isSubtree = function(root, subRoot) {
const 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 isSameTree(p.left,q.left) && isSameTree(p.right,q.right)
}
if(root === null){
return subRoot === null
}
// 判断以root为根的二叉树和sub是否相同
if(isSameTree(root,subRoot)) return true
// 没有则去判断左右子树
return isSubtree(root.left,subRoot) || isSubtree(root.right,subRoot)
};
总结
可以看到,我们解决左右子树比较问题的时候。把问题进行拆分,对左右子树分别建立递归思想解题会比较容易。