面试题07.重建二叉树
题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
解题思路:
1.前序遍历的第一个数字总是树的根节点的值。但在中序遍历中,根节点的值在序列的中间,其中左子树的节点的值位于根节点的值的左边,右子树的节点的值位于根节点的值的右边。要扫描中序遍历序列,才能找到根节点的值。
2.又因为前序遍历总是在根节点后先遍历完左子树,才会遍历右子树,所以由后续遍历推断出左子树中节点的数目之后,前序遍历中根节点之后的相同数目的值都是左子树的节点的值。剩下的就是右子树的值。这样就分别找到了左右子树序列。
3.分别确定了根节点和左右子树的前序、中序遍历,我们可以用同样的方法构建左右子树,剩下的可以用递归来完成。
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) {
if (pre.empty() || vin.empty())
return NULL;
//创建根节点
TreeNode* root;
//从pre[0]开始扫描
int indp = 0;
recurConstruct(vin.begin(), vin.end(), pre, vin, root, indp);
return root;
}
//注意TreeNode* &p要用引用,或者指针的指针,否则改变不了实参的
void recurConstruct(vector<int>::iterator startin, vector<int>::iterator endin, vector<int> pre, vector<int> vin, TreeNode* &p, int &indp){
if (indp>vin.size()-1||endin<startin)
return;
p=new TreeNode(pre[indp]);
vector<int>::iterator pos;
//找到当前根节点的位置
pos = find(startin, endin, pre[indp]);
indp++;
//中序遍历中,根节点左边为左子树,右边为右子树
if (pos != startin)
recurConstruct(startin, pos - 1, pre, vin, p->left, indp);
recurConstruct(pos + 1, endin, pre, vin, p->right, indp);
return;
}
};
面试题09.用两个栈实现队列
题目描述:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
method:用两个栈,一个栈做入栈,一个栈做出栈。入栈的时候存入元素,出栈的时候删除元素。
class Solution
{
public:
void push(int node) {
while(!stack2.empty())
{
stack1.push(stack2.top());
stack2.pop();
}
stack1.push(node);
}
int pop() {
while(!stack1.empty())
{
stack2.push(stack1.top());
stack1.pop();
}
int result=stack2.top();
stack2.pop();
return result;
}
private:
stack<int> stack1;
stack<int> stack2;
};
参考博客:https://blog.csdn.net/m0_37950361/article/details/82531649