前言
跟着上一篇走。。。
对称二叉树
首先用递归实现
function mirrior(root) {
function help(r1, r2) {
if (!r1 && !r2) return true;
if (!r1 || !r2 || r1.val !== r2.val) return false;
return help(r1.left, r2.right) && help(r1.right, r2.left);
}
if (!root) return true;
return help(root.left, root.right);
}
接着用循环实现
function mirrior(root) {
if (!root) return true;
let queue = [root.left, root.right];
while (queue.length) {
let n1 = queue.shift();
let n2 = queue.shift();
if (!r1 && !r2) continue;
if (!r1 || !r2 || r1.val !== r2.val) return false;
queue.push(r1.left);
queue.push(r2.right);
queue.push(r1.right);
queue.push(r2.left);
}
return true;
}
二叉树的直径问题
这道题有一点很坑的是最长路径不一定经过根节点。
function longR = (root) => {
let maxDepth = (root) => {
if(!root) return 0
return Math.max(maxDepth(root.left), maxDepth(root.right))
}
let help = (root) => {
if(!root) return 0
let max1 = maxDepth(root.left)+maxDepth(root.right)
let max2 = Math.max(help(root.left), help(root.right))
return Math.max(max1, max2)
}
if(!root) return 0
return help(root)
}
这是优化之后的
function longR = (root) => {
let max = 0
let help = (root) => {
if(!root) return 0
let left = root.left?help(root.left)+1:0
let right = root.right?help(root.right)+1:0
let cur = left+right
if(cur>max) max = cur
return Math.max(left, right)
}
if (!root) return 0
help(root)
return max
}
二叉树的所有路径
首先使用递归
function allPath(root) {
let res = [], path = []
let help = (root) => {
if(!root) return
path.push(root)
help(root.left)
help(root.right)
if(!root.left&&!root.right) {
res.push(path.map(item=>item.val).join('->'))
}
path.pop()
}
help(root)
return res
}
接着使用循环,后序遍历
function allPath(root) {
if(!root) return []
let stack = [], res = [], p = root, dic = new Set()
while(stack.length||p){
while(p){
stack.push(p)
p = p.left
}
let node = stack.slice(-1)[0]
if(!node.right && !node.left){
res.push(stack.map(item=>item.val).join('->'))
}
if(node.right&&!dic.has(node.right)){
p = node.right
dic.add(p)
} else {
stack.pop()
}
}
return res
}
二叉树的最大路径和
function maxPathSum(root) {
let help=(root) =>{
if(!root) return 0
let left = Math.max(help(root.left), 0)
let right = Math.max(help(root.right), 0)
let cur = left+root.val+right
if(cur>max) max=cur
return Math.max(left, right)+root.val
}
let max = Number.MIN_SAFE_INTEGER
help(root)
return max
}
验证二叉搜索树
首先是中序遍历的方法
function isValid(root){
let pre = null
let help = root => {
if(!root) return true
if(!help(root.left)) return false
if(pre!==null && pre>=root.val) return false
pre = root.val
return help(root.right)
}
return help(root)
}
限定上下界进行DFS的方法,分为递归和循环
function isBST(root) {
let help = (root, max, min) =>{
if(!root) return true
if(root.val>=max || root.val<=min) return false
return help(root.left, root.val, min) && help(root.right, max, root.val)
}
return help(root, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_NUMBER)
}
function isBST(root) {
if(!root) return true
let stack = [root], max = Number.MAX_SAFE_INTEGER, min = Number.MIN_SAFE_NUMBER
root.max = max, root.min = min
while(stack.length){
let node = stack.pop()
if(node.val>=node.max || node.val<=node.min) return false
if(node.left) {
stack.push(node.left)
node.left.max = node.val
node.left.min = node.min
}
if(node.right) {
stack.push(node.right)
node.right.min = node.val
node.right.max = node.max
}
}
return true
}
将有限数组转化为BST
function changeToBST(nums) {
let help = (start, end) => {
if(start>end) return null
if(start===end) return new TreeNode(nums[start])
let mid = Math.floor((start+end)/2)
let node = new TreeNode(nums[mid])
node.left = help(start, mid-1)
node.right = help( mid+1, end)
return node
}
return help(0, nums.length-1)
}
二叉树展开为链表
递归
function changeToList(root) {
if(!root) return
changeToList(root.left)
changeToList(root.right)
if(root.left){
let p = root.left
while(p.right){
p = p.right
}
p.right = root.right
root.right = root.left
root.left = null
}
}
循环
function changeToList(root) {
if(!root) return
let stack = [], p = root, dic = new Set()
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(p)
} else {
if(node.left) {
let pp = node.left
while(pp.right) {
pp = pp.right
}
pp.right = node.right
node.right = node.left
node.left = null
}
stack.pop()
}
}
}
不同的二叉搜索树
function allBST(n) {
if(!n) return []
let help = (start, end) =>{
if(start>end) return [null]
if(start===end) return [new TreeNode(start)]
let res = []
for(let i = start; i<=end; i++) {
let left = help(start, i-1)
let right = help(i+1, end)
for(let j = 0; j<left.length; j++) {
for(let k = 0; k<right.length; k++) {
let node = new TreeNode(i)
node.left = left[j]
node.right = right[k]
res.push(node)
}
}
}
return res
}
return help(1,n)
}