一 目录
不折腾的前端,和咸鱼有什么区别
目录 |
---|
一 目录 |
二 前言 |
三 解题及测试 |
四 LeetCode Submit |
五 解题思路 |
六 进一步思考 |
二 前言
-
难度:简单
-
涉及知识:树
-
题目地址:https://leetcode-cn.com/problems/subtree-of-another-tree/
-
题目内容:
给定两个非空二叉树 s 和 t,
检验 s 中是否包含和 t 具有相同结构和节点值的子树。
s 的一个子树包括 s 的一个节点和这个节点的所有子孙。
s 也可以看做它自身的一棵子树。
示例 1:
给定的树 s:
3
/ \
4 5
/ \
1 2
给定的树 t:
4
/ \
1 2
返回 true,因为 t 与 s 的一个子树拥有相同的结构和节点值。
示例 2:
给定的树 s:
3
/ \
4 5
/ \
1 2
/
0
给定的树 t:
4
/ \
1 2
返回 false。
三 解题及测试
小伙伴可以先自己在本地尝试解题,再回来看看 jsliang 的解题思路。
-
LeetCode 给定函数体:
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} s
* @param {TreeNode} t
* @return {boolean}
*/
var isSubtree = function(s, t) {
};
根据上面的已知函数,尝试破解本题吧~
确定了自己的答案再看下面代码哈~
index.js
/**
* @name 树的万能公式
* @param {Object} root 树
*/
const ergodic = (root) => {
if (!root) {
return '!#';
}
return '!' + root.val + ergodic(root.left) + ergodic(root.right);
}
/**
* @name 另一个树的子树
* @param {TreeNode} s
* @param {TreeNode} t
* @return {boolean}
*/
const isSubtree = (s, t) => {
const sNodes = ergodic(s);
const tNodes = ergodic(t);
return sNodes.includes(tNodes);
};
// 示例 1: true
const s = {
val: 3,
left: {
val: 4,
left: { val: 1, left: null, right: null },
right: { val: 2, left: null, right: null },
},
right: { val: 5, left: null, right: null },
};
const t = {
val: 4,
left: { val: 1, left: null, right: null },
right: { val: 2, left: null, right: null },
};
// 示例 2: false
// const s = {
// val: 3,
// left: {
// val: 4,
// left: { val: 1, left: null, right: null },
// right: {
// val: 2,
// left: { val: 0, left: null, right: null },
// right: null,
// },
// },
// right: { val: 5, left: null, right: null },
// };
// const t = {
// val: 4,
// left: { val: 1, left: null, right: null },
// right: { val: 2, left: null, right: null },
// };
console.log(isSubtree(s, t));
node index.js
返回:
true
四 LeetCode Submit
Accepted
* 176/176 cases passed (80 ms)
* Your runtime beats 98.55 % of javascript submissions
* Your memory usage beats 11.63 % of javascript submissions (40.8 MB)
五 解题思路
首先,拿到题目,开始发愣:
-
我记得有次滑铁卢,就是比较两棵树。
所以,这次我要好好想想……
然后,突然发现,我比较两棵树可能不行,但是如果我将两棵树遍历成字符串,会不会比较好比较:
/**
* @name 树的万能公式
* @param {Object} root 树
*/
const ergodic = (root) => {
if (!root) {
return '!#';
}
return '!' + root.val + ergodic(root.left) + ergodic(root.right);
}
/**
* @name 另一个树的子树
* @param {TreeNode} s
* @param {TreeNode} t
* @return {boolean}
*/
const isSubtree = (s, t) => {
const sNodes = ergodic(s);
const tNodes = ergodic(t);
return sNodes.includes(tNodes);
};
代码贼简单有木有!
示例 1 和示例 2 都搞定了有木有!
Submit 提交看看:
Accepted
* 176/176 cases passed (80 ms)
* Your runtime beats 98.55 % of javascript submissions
* Your memory usage beats 11.63 % of javascript submissions (40.8 MB)
Perfect!
最后,讲讲思路:
-
通过万能公式遍历树:
ergodic(root)
,拿到返回的字符串。 -
将两个字符串进行比较,如果
t
包含在s
内,就返回true
即可。
六 进一步思考
最后的最后,当然是惯例翻一下【题解区】和【评论区】啦,想看看正经点的解题步骤是怎样的~
官方题解
-
https://leetcode-cn.com/problems/subtree-of-another-tree/solution/ling-yi-ge-shu-de-zi-shu-by-leetcode/
官方题解,仅有讲解,没有代码。
-
解法 1 的先序遍历看起来跟我的解法一致。
-
解法 2 的方法是:将 s 树进行遍历,每个节点都和 t 的根节点进行比较,如果相同,则进一步比较 s 当前节点(子节点)和 t 所有节点进行比较,如果成功则返回
true
,否则返回false
。
闷骚解法
-
https://leetcode-cn.com/problems/subtree-of-another-tree/solution/li-yong-javascriptde-jsonstringifyhan-shu-tou-ji-q/
var isSubtree = function(s, t) {
return JSON.stringify(s).includes(JSON.stringify(t));
};
Submit 提交:
Accepted
* 176/176 cases passed (84 ms)
* Your runtime beats 94.2 % of javascript submissions
* Your memory usage beats 39.53 % of javascript submissions (38.9 MB)
看起来非常简洁高效有木有!o(╥﹏╥)o比我写的方法好多了,效率等也高。
最重要的是,它仅有一行!
以上,就是本题的破解及延伸啦~
如果小伙伴们碰到更新奇或者更清晰的解法,欢迎留言评论或者私聊我~
不折腾的前端,和咸鱼有什么区别!
jsliang 会每天更新一道 LeetCode 题解,从而帮助小伙伴们夯实原生 JS 基础,了解与学习算法与数据结构。
浪子神剑 会每天更新面试题,以面试题为驱动来带动大家学习,坚持每天学习与思考,每天进步一点!
扫描上方二维码,关注 jsliang 的公众号(左)和 浪子神剑 的公众号(右),让我们一起折腾!
jsliang 的文档库 由 梁峻荣 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。