算法笔记-从前序中序构建二叉树

76 阅读1分钟

构建二叉树是Leetcode Top100,原理不难,难在细节把控,因此分享下踩坑心得。

构建思路

1.前序的第一个元素是二叉树根节点,该元素在中序数组的左边刚好是左子树的中序序列,右边是右子树的中序序列。

2.递归法是,使用前序第一个元素找出节点值,然后根据该元素找出节点的左子树和右子树,通过不断挖前序第一个元素,二叉树就构建好了。

3.挖前序第一个元素和该元素左右子树的边界值:子树长度为0=>该子树为nullptr;子树长度为1=>该子树就是叶子节点。

踩坑分析

私以为构建思路不难,难的是实现过程中切分左子树、右子树边界的计算:

四个计算量,搞混就没法继续了。

int rootIndexOfInorderVec = indexOfElementInVector(inorder, rootVal);
int leftSize = rootIndexOfInorderVec - inLeft;

int inorderBeginOfLeft = inLeft;
int inorderEndOfLeft = rootIndexOfInorderVec;
int inorderBeginOfRight = rootIndexOfInorderVec + 1;
int inorderEndOfRight = inRight;
  
int preorderBeginOfLeft = preLeft + 1;
int preorderEndOfLeft = preLeft + 1 + leftSize;
int preorderBeginOfRight = preorderEndOfLeft;
int preorderEndOfRight = preRight;

写这个题的时候,有一个bug调试了很久,发现是找根元素的子函数写错了。

int indexOfElementInVector(vector<int>& vec, int elementVal) {
    /* Wrong implements
    int index = 0;
    while(index < vec.size()) {
        if (vec[index++] == elementVal) { return index;}
    }
    */
    for (int i = 0; i < vec.size(); i++) {
        if (vec[i] == elementVal) { return i; }
    }
    return -1;
}

想法

  • 整体和细节是两种思维,写实现的时候同时过算法流程,容易出错。
  • 简单功能没必要直接封装函数,debug时容易忽略。