[路飞]_算法·每日解读--前序与中序遍历构造二叉树

135 阅读2分钟

「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

题解105: leetcode-从前序与中序遍历序列构造二叉树

根据前序遍历和中序遍历的特性,组合相交便能确定一个二叉树的整体结构

首先要充分的明白二叉树的三种遍历方式:dianjingwenzhang==>二叉树的三种遍历方法

接下来根据不同的遍历方法的特性来剥离重点:

  • 根据节点在前序和中序遍历中存储时的特殊位置,我们可以快速的找出根节点
  • 接下来便是循环逐个节点进行对比,确定左右节点或空节点

解题逻辑:

  1. 根据遍历的特性可知,前序遍历数组的第一个元素,便是整个树的root

  2. 在中序遍历数组中,找到根节点的位置,便可将二叉树分隔成左右两部分

    左子树:iStart ~ mid-1 || 右子树:mid+1 ~ inorder.length-1

  3. 获取左子节点个数leftNum 用来获取在前序遍历数组中左子树和右子树的分割点

    左子树:pStart+1 ~ pStart+leftNum || 右子树:pStart+leftNum+1 ~ preorder.length-1

  4. 咱上面步骤分别去构建左右子树

上代码:

var buildTree = function (preorder, inorder) {
  // 创建map地图,将中序遍历中的每个元素存进去
  let map = new Map();
  for (let i = 0; i < inorder.length; i++) {
    // 将值和坐标存进去,形成键值对
    map.set(inorder[i], i);
  }
​
  // 第一步:找到根节点
  const helper = function (pStart, pEnd, iStart, iEnd) {
    if (pStart > pEnd) return null;
    //获取根节点的值
    let rootVal = preorder[pStart];
    // 构造一个根节点
    let root = new TreeNode(rootVal);
​
    //如何判定左右的结束点
    // 获取根节点在中序遍历数组中的索引位置,来分隔左右子树
    let mid = map.get(rootVal);
    // 查找左节点和右节点,先进行左右数组切分  左:0~mid-1    || 右  mid+1~min.length-1
    let leftNum = mid - iStart;
    // 进行数据的分组,左为左,右为右::递归操作
    root.left = helper(pStart + 1, pStart + leftNum, iStart, mid - 1);
    root.right = helper(pStart + leftNum + 1, pEnd, mid + 1, iEnd);
    return root;
  };
  return helper(0, preorder.length - 1, 0, inorder.length - 1);
};

灵魂总结:①定根 ②定左右 ③左右定根定左右

👆 👆 以上就是个人对【复制带随机指针的链表】的代码解法和方法解读。

迷惑重重,一看上头,一键三连哟!!!

完成代码请移步: 稍后添加