【发布时间】:2020-07-21 13:49:16
【问题描述】:
我有以下代码:
class TreeNode {
constructor(val) {
this.val = val
this.left = this.right = null
}
}
const isSymmetric = root => {
if (!root) return true
let stackP = []
let stackQ = []
let currentP = root
let currentQ = root
while ((currentP && currentQ) || (stackP.length && stackQ.length)) {
while (currentP) {
stackP.push(currentP)
currentP = currentP.left
}
while (currentQ) {
stackQ.push(currentQ)
currentQ = currentQ.right
}
console.log(stackP, stackQ, 'after push')
currentP = stackP.pop()
currentQ = stackQ.pop()
console.log(stackP, stackQ, 'after 1 iterative pop')
if ((currentP.val !== currentQ.val) || (stackP.length !== stackQ.length)) return false
console.log(currentP, currentQ, 'after if statement')
// confused as to why we are setting it to the opposite here
currentP = currentP.right
currentQ = currentQ.left
console.log(currentP, currentQ, 'after opp DECLARATION')
}
return true
}
//example 1
const tree1 = new TreeNode(1)
tree1.left = new TreeNode(2)
tree1.right = new TreeNode(2)
tree1.left.left = new TreeNode(3)
tree1.left.right = new TreeNode(4)
tree1.right.left = new TreeNode(4)
tree1.right.right = new TreeNode(3)
//example 2
const tree2 = new TreeNode(1)
tree2.left = new TreeNode(2)
tree2.right = new TreeNode(2)
tree2.left.right = new TreeNode(3)
tree2.right.right = new TreeNode(3)
console.log(isSymmetric(tree1));
console.log(isSymmetric(tree2));
但是,我对以下两行感到困惑:
currentP = currentP.right
currentQ = currentQ.left
我不确定为什么要这样做。我尝试跟随控制台日志记录,但无法跟随。我希望currentP 能够按照设置在左侧的原始模式保持自身,但似乎在弹出P 和Q 之后它们现在正在向右移动。我不明白为什么。谁能澄清一下?
假设我们有以下树
A
/ \
B B
/ \ / \
C D D C
跟踪 currentP 和 currentQ 应该给出以下值 A、B、C、C、null、B、D、null、A。但是当我们通过逻辑到达 A 时,似乎我们处于无限循环。除非我没有正确跟踪它。在我们将 currentP 和 currentQ 声明为“A”之后,我们应该再次进入 while 循环,基本上将 B 和 C 再次推回,我是否遗漏了什么?
【问题讨论】:
-
只需将根的左右子树视为两棵不同的树。然后,同时遍历两者,如果它们在任何时候发散,你就有了答案。这就像一次在两棵树中执行 DFS,如果在某个时刻一个节点为空而另一个不是,那么您会发现不同之处。您可以迭代地执行此操作,但递归似乎更容易实现。
标签: javascript algorithm tree iteration