前言
出不了门,在家做题
二叉树的遍历
分别用前中后三种遍历方式,先递归再循环,首先第一个是数的定义。
function TreeNode = (val) => {
this.val = val;
this.left = null;
this.right = null;
}
前序
const preOrder = (root) => {
if(!root) return []
return [root.val, ...preOrder(root.left), ...preOrder(root.right)]
}
const preOrder = (root) => {
if(!root) return []
let stack = [], res = []
stack.push(root)
while(stack.length) {
let node = stack.pop()
res.push(node.val)
if(node.right) stack.push(node.right)
if(node.left) stack.push(node.left)
}
return res
}
中序
const innerOrder = (root) => {
if(!root) return []
return [...innerOrder(root.left), root.val, ...innerOrder(root.right)]
}
const innerOrder = (root) => {
if(!root) return []
let stack = [], res = [], p = root
while(stack.length || p) {
while(p) {
stack.push(p)
p = p.left
}
let node = stack.pop()
res.push(node.val)
p = node.right
}
return res
}
后序
function backOrder = (root) => {
if(!root) return []
return [...backOrder(root.left), ...backOrder(root.right),root.val]
}
function backOrder = root => {
if(!root) return []
let stack = [], res= [], dic = new Set(),p = root
while(stack.length || p) {
while(p) {
stack.push(p)
p = p.left
}
let node = stack.slice(-1)[0]
if(node.right && !dic.has(node.right)) {
p = node.right
dic.add(node.right)
} else {
res.push(node.val)
stack.pop()
}
}
return res
}
二叉树的最大(最小)深度
换个方式,先用递归求两个深度,在使用循环
function maxDepth(root) {
if(!root) return 0
return Math.max(maxDepth(root.left)+1, maxDepth(root.right)+1)
}
function minDepth(root) {
if(!root) return 0
if(root.left && root.right) {
return Math.min(minDepth(root.left), minDepth(root.right))+1
} else {
return Math.max(minDepth(root.left), minDepth(root.right))+1
}
}
接着使用DFS循环
function maxDepth(root) {
if(!root) return 0
let queue = [root], level = 0;
while(queue.length) {
let size = queue.length
while(size--) {
let front = queue.shift()
if(front.left) queue.push(front.left)
if(front.right) queue.push(front.right)
}
level++
}
return level
}
function minDepth(root) {
if(!root) return 0
let queue = [root], level = 0
while(queue.length) {
let size = queue.length
while(size--) {
let front = queue.shift()
if(!front.left&& !front.right) return level+=1
if(front.left) queue.push(front.left)
if(front.right) queue.push(front.right)
}
level++
}
return level
}
二叉树的最近公共祖先
还是循环和递归
function closedAns(root, p, q) {
if(!root || root===p ||root===q) return root
let set = new Set(), map = new Map(), queue = [root]
while(queue.length){
let size = queue.length
while(size--) {
let front = queue.shift()
if(front.left) {
queue.push(front.left)
map.set(front.left, front)
}
if(front.right) {
queue.push(front.right)
map.set(front.right, front)
}
}
}
while(q) {
set.add(q)
q = map.get(q)
}
while(p){
if(set.has(p)) return p
p = map.get(p)
}
}
function closedAns(root, p, q) {
if(!root || root===q || root===p) return root
let left = closedAns(root.left, p, q)
let right = closeAns(root.right, p, q)
if(!left) return right
else if(!right) return left
return root
}
二叉搜索树的最近公共祖先
由于二叉搜索树的特性,我们可以使用这种递归:
function searchClosedAns(root, p, q) {
if(!root || root===q || root===p) return root
if(root.val> Math.max(q.val, p.val)) return searchClosedAns(root.left, p, q)
if(root.val < Math.min(q.val, p.val)) return searchClosedAns(root.right, p,q)
return root
}
当然也有循环的方式
function searchClosedAns(root, p, q) {
while(root) {
if(root.val>Math.max(q.val, p.val)) root = root.left
else if(root.val<Math.min(q.val, p.val)) root = root.right
else return root
}
}