二叉树 树形DP题目套路(构造递归结构)---平衡二叉树、搜索二叉树、满二叉树

124 阅读2分钟

树形DP套路--构造递归结构

  • 递归结构:需要的信息,后序由每一个节点根据左右子树进行加工返回
  • 一般通过process(node.left);process(node.right)的顺序,拿到递归结构,从最底层的节点,考虑左右子树的情况进行加工返回;(动态规划)

题目

返回一颗树是不是平衡二叉树,平衡二叉树定义:所有子树都满足自身左右子树高度差不大于1

  • 如果一颗树的头节点的左子树满足平衡二叉树,右子树满足平衡二叉树,且左右子树高度不小于1,那整颗树就是平衡二叉树
  • 则构造递归结构,只需要从最下面的叶子节点开始,判断是否满足平衡二叉树,依次往上回退
    • 对于父节点要想知道自身是否满足平衡二叉树,就得知道左右子节点的高度并且左右节点是否是平衡二叉树,所以递归返回的结构得知道子节点的高度和子节点是否是平衡二叉树
function factory(node, isBalance, height) {
  node.isBalance = isBalance;
  node.height = height;

  return node;
}

function balance(node) {
  //如果一颗树没有子节点,那也满足平衡二叉树
  if (node == null) {
    return factory(node, true, 0);
  }

  let leftNode = balance(node.left);
  let rightNode = balance(node.right);
  //根据左右子树最大高度,获取当前节点高度
  let height = Math.max(leftNode.height, rightNode.height) + 1;
  //根据左右子树是否是平衡二叉树,并且左右子树高度是否<2来判断当前节点是否是平衡二叉树
  let isBalance =
    leftNode.isBalance &&
    rightNode.isBalance &&
    Math.abs(leftNode.height - rightNode.height) < 2;

  return factory(node, isBalance, height);
}

console.log(balance(node).isBalance);

题目

判断一颗树是不是搜索二叉树,搜索二叉树的左树一定比当前节点小,右树一定比当前节点大。

  • 构造递归结构,每个节点返回以该节点为根节点的所在树的最大值、最小值和是否是搜索二叉树大布尔值,
function searchOrder(node) {
  if (!node) {
    return null;
  }

  let min = node.value;
  let max = node.value;
  let isBST;

  let leftData = searchOrder(node.left);
  let rightData = searchOrder(node.right);

  if (leftData != null) {
    min = Math.min(min,leftData.min);
    max = Math.max(max,leftData.max);
  }

  if (rightData != null) {
    min = Math.min(min,rightData.min);
    max = Math.max(max,rightData.max);
  }

  isBST = true;
  if (leftData != null && (!leftData.isBST || leftData.max >= node.value)) {
    isBST = false;
  }
  if (rightData != null && (!rightData.isBST || rightData.min) <= node.value) {
    isBST = false;
  }
  return { isBST, min, max };
}

题目

判断一颗树是否是满二叉树

  • 构造递归结构(即要收集的信息),然后对递归结构返回的信息进行判断
  • 对于这道题,需要收集的信息是节点的高度和节点的数量,每个节点都放回所在树的该结构
function isAllBST(node) {
  let data = collect(node);
  //节点数量是否等于2的树高度的次方-1
  return data.nodeNum == 1 << (data.height - 1);

  function collect(node) {
    let height;
    let nodeNum;

    if (!node) {
      height = 0;
      nodeNum = 0;
      return {
        height,
        nodeNum,
      };
    }

    let leftData = isAllBST(node.left);
    let rightData = isAllBST(node.right);

    height = Math.max(leftData.height, rightData.height) + 1;
    nodeNum = leftData.nodeNum + rightData.nodeNum + 1;

    return {
      height,
      nodeNum,
    };
  }
}