构建二叉树是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时容易忽略。