开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第14天,点击查看活动详情
1.二叉树的层序遍历
题目描述
解题思路
1.二叉树的层序遍历需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
2.使用队列将每一层的节点存起来,同时将下一层节点加入队列中。
var levelOrder = function(root) {
const queue = [];
const result = [];
if(root == null) {
return []
}
queue.push(root)
while(queue.length) {
const size = queue.length
let tmp = []
for(let i = 0;i<size;i++) {
const node = queue.shift();
tmp.push(node.val)
node.left && queue.push(node.left)
node.right && queue.push(node.right)
}
result.push(tmp)
}
return result
};
2.翻转二叉树
题目描述
解题思路
1.翻转二叉树可以使用递归法,把每个节点的左右节点交换即可。
2.递归三要素:确认递归参数和返回值、确定递归终止条件、确认单层逻辑
3.本题递归参数就是一个节点,返回为左右子树交换后的根节点,当节点为空时返回,单层逻辑为交换传入节点的左右子节点。
var invertTree = function(root) {
const inverNode=function(left,right){
let temp=left;
left=right;
right=temp;
//需要重新给root赋值一下
root.left=left;
root.right=right;
}
//确定递归函数的参数和返回值inverTree=function(root)
//确定终止条件
if(root===null){
return root;
}
//确定节点处理逻辑 交换
inverNode(root.left,root.right);
invertTree(root.left);
invertTree(root.right);
return root;
};
除此之外,还可以使用迭代法来交换二叉树
var invertTree = function(root) {
if(root===null){
return null
}
const stack = []
stack.push(root)
function swap(root,left,right){
let temp = left;
left = right;
right = temp
root.left = left
root.right = right
}
while(stack.length){
const node = stack.pop()
swap(node,node.left,node.right)
node.left&& stack.push(node.left)
node.right&& stack.push(node.right)
}
return root
};
3.对称二叉树
题目描述
解题思路
对于二叉树是否对称,要比较的是根节点的左子树与右子树是不是相互翻转的,理解这一点就知道了其实我们要比较的是两个树(这两个树是根节点的左右子树) ,所以在递归遍历的过程中,也是要同时遍历两棵树。
本题同样采用递归法求解:
1.确认递归参数和返回值,本题需要同时比较左右子树,所以传入的参数是左右子树,返回值为bool值
2.确认递归终止条件,如果左右节点都不为空,若节点值不等返回false;若左空右不空,返回false,左不空右空,返回false,左右节点都为空,返回true
3.确认单层逻辑,比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子;比较内测是否对称,传入左节点的右孩子,右节点的左孩子;如果左右都对称就返回true ,有一侧不对称就返回false 。
var isSymmetric = function(root) {
var compare = function(left,right) {
if(left == null &&right !== null) { // 左空 右不空
return false
} else if(left!==null&&right == null) { // 右空左不空
return false
} else if(left == null&&right==null) { // 左右都空
return true
} else if(left.val !== right.val) { // 左右节点不同 剩下的就是左右节点相同情况 继续判断子节点
return false
}
let outside = compare(left.left,right.right)
let inside = compare(left.right,right.left) // 比较子树的左右测
return outside && inside // 内外侧都对称才是对的
}
return compare(root.left,root.right)
};
迭代法
var isSymmetric = function(root) {
// 栈
if (root === null) return true
const stack = []
stack.push(root.left)
stack.push(root.right)
while(stack.length){
const right = stack.pop() // 成对取出
const left = stack.pop()
if(left===null&&right===null){
continue
}
if(left === null || right === null||left.val!==right.val){
return false
}
stack.push(left.left) // 成对添加 外侧
stack.push(right.right)
stack.push(left.right) // 内侧
stack.push(right.left)
}
return true
};