题目描述
输入一棵二叉树前序遍历和中序遍历的结果,请重建该二叉树。
注意:
- 如果给定的节点是中序遍历序列的最后一个节点,则返回空节点;
- 二叉树一定不为空,且给定的节点一定不是空节点
样例
假定二叉树为:[2,1,3,null.null,null,null]
Input: 值等于2的节点
Output: 值等于3的节点
该的二叉树如下所示:
2
/ \
1 3
解题思路
-
普通思路
-
描述
中序遍历二叉树并将节点通过vector存储,然后遍历vector查找即可。 -
实现代码:
/* 包含头文件: #include <vector> 结构体: struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int val) { this->val = val; this->left = NULL; this->right = NULL; } }; */ vector<TreeNode*> inNode; //存储中序遍历的二叉树节点 int index; //存储指定节点在inNode中的位置 void inorder(TreeNode* head,TreeNode* search) { if (head != NULL) { inorder(head->left,search); inNode.push_back(head); if(head == search) { index = inNode.size() - 1; } inorder(head->right,search); } }
-
复杂度分析
时间复杂度: ≈ O ( n ) \approx O(n) ≈O(n)
遍历递归次数与节点数有关,虽不知具体是多少,但是一定是一个线性关系
空间复杂度: O ( n + 1 ) ≈ O ( n ) O(n + 1) \approx O(n) O(n+1)≈O(n)
使用一个vector类型变量和一个int类型变量
-
-
高级思路
-
描述
本题目可以针对不同情况进行分析。题目要求找到节点的后继节点,按照中序遍历规则"左根右",则分情况当前节点的右子树是否存在。
-
当前节点右子树不为空
获取右子树,右子树最左边的节点即为下一个节点
-
当前节点右子树为空
找到当前节点的父节点,如果该节点是父节点的左节点,则后继节点即为该父节点。
-
-
实现代码:
/* 包含头文件: #include <vector> 结构体: struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode* father; //存储当前节点的父节点 TreeNode(int val) { this->val = val; this->left = NULL; this->right = NULL; this->father = NULL; } }; */ TreeNode* inorderSuccessor(TreeNode* p) { if(p->right) //当前节点的右子树存在 { p = p->right; //赋值为右子树 while(p != NULL) //寻找最左节点,返回 { p = p->left; } return p; } while(p->father && p == p->father->right) //父节点存在,且该节点为父节点的右节点 { p = p->father; } return p->father; //如果是while第一个条件失败,则返回的是一个空父节点 //如果是while第二个条件失败,则返回的是父节点(此为后继节点) }
-
复杂度分析
时间复杂度: O ( l o g n ) O(log^n) O(logn)
从当前节点向下或向上按照一种路径搜索,当然是 l o g n log^n logn
空间复杂度: O ( 0 ) O(0) O(0)
不需要任何辅助变量
-