题目说明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| 给定两个非空二叉树 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。
|
说明
解题之间看清除问题中的两个例子,什么是子树。
树中的某节点及其所有子节点组成的树,叫子树。不可以漏掉一个的。所以看例2,是返回false的哦。
解题思路一
广度优先找子树根,深度优先对比s,t。我这种思路可能稍麻烦些,但是好在容易理解。符合人脑回路。
- 广度优先遍历S树。依赖队列实现(
push和shift配合实现队列先进先出的特点)
- 直到S树某节点的val值和T树的根节点val值相同时。
(s.val === t.val)
- 深度遍历做对比。使用
递归
还有一种思路是依赖JSON.stingify将对象转换成字符串,再判断字符串之间是否包含。投机取巧不太可取就不做展示了。
代码实现一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
var isSubtree = function(s, t) { let sArr = []; let tArr = []; let dp = [s]; let flag = 'default'; function frontTree(s, t) { if (t === null || s === null || s.val !== t.val) { return (flag = false) } if ((s.left && !t.left) || (!s.left && t.left)) { return (flag = false) } if ((s.right && !t.right) || (!s.right && t.right)) { return (flag = false) } if (s.left && t.left) { frontTree(s.left, t.left); } if (s.right && t.right) { frontTree(s.right, t.right); } } while (dp.length) { let s = dp.shift(); if(s.val === t.val) { flag = true; frontTree(s, t); if (flag) { return true } } s.left && dp.push(s.left) s.right && dp.push(s.right) } return flag === 'default' ? false : flag };
|