几个二叉树和二叉搜索树的题目

前言

跟着上一篇走。。。

对称二叉树

首先用递归实现

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)
}
发布了371 篇原创文章 · 获赞 391 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_43870742/article/details/104248831
今日推荐