剑指offer 面试题6 重建二叉树

原文链接

剑指offer 重建二叉树

提交网址:  http://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?tpId=13&tqId=11157
或 leetcode 105:  https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

参与人数:5246  时间限制:1秒  空间限制:32768K

题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。


分析:

剑指offer 面试题6 重建二叉树_第1张图片


如图所示,先在中序中找到根节点的位置inRootpos,然后根节点左边递归地生成左子树,根节点右边递归地生成右子树.

其中preRootpos是逐一右移的.

#include
#include
using namespace std;
struct TreeNode
{
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x):val(x),left(NULL),right(NULL)
	{}
};
class Solution
{
	public:
		struct TreeNode* reConstructBinaryTree(vector pre,vector in)
		{
			if(pre.size()!=in.size()||pre.size()==0||in.size()==0)return NULL;
			else
			{
				TreeNode* inRoot=createTreeHelper(pre,in,0,0,in.size()-1);
				return inRoot;
			}
		}
		TreeNode* createTreeHelper(vector pre,vector in,int preRootpos,int inLeft,int inRight)
		{//pre:前序,in:中序,preRootpos:前序中的根节点,inLeft:中序中的左边界,inRigth:中序中的右边界 
			int inRootpos,RootVal;
			RootVal=pre[preRootpos];//根节点的值 
			//不建议使用.at()取下标的值
			if(inLeft>inRight) return NULL;
			for(int i=inLeft;i<=inRight;i++)
			{
				if(in[i]==RootVal)
				{
					inRootpos=i;
					//找到根节点在中序中的位置
					//for循环中循环完成后增量i无法使用,于是全局变量存储下来 
				}
			}
			int leftLen=inRootpos-inLeft;//这里的inRootpos是中序中根节点的位置
			//leftLen为根节点距离左边界的长度
			//即左子树的长度
			//右子树的的根节点的位置就是 preRootpos+左子树的长度+1  
			 
			TreeNode* inRoot=new TreeNode(RootVal);
			inRoot->left=createTreeHelper(pre,in,preRootpos+1,inLeft,inRootpos-1);
			inRoot->right=createTreeHelper(pre,in,preRootpos+leftLen+1,inRootpos+1,inRight); 
			return inRoot; 
		}
};
void Intraverse(TreeNode *pRoot)
{
	if(pRoot == NULL) return ;
	Intraverse(pRoot->left);//遍历左子树
	cout<val<<" ";//访问根节点
	Intraverse(pRoot->right);//遍历右子树 
}
void PostTraverse(TreeNode *pRoot)
{
	if(pRoot == NULL) return ;
	PostTraverse(pRoot->left);//后序遍历左子树
	PostTraverse(pRoot->right);//后序遍历右子树
	cout<val<<" ";//访问根节点 
} 
int main()
{
	int arrA[8]={1,2,4,7,3,5,6,8};
	int arrB[8]={4,7,2,1,5,3,8,6};
	vector a(arrA,arrA+8);
	vector b(arrB,arrB+8);

	Solution sol;
	TreeNode *root;
	root =sol.reConstructBinaryTree(a,b);
	PostTraverse(root);
	
	return 0;
	
	//测试成功
	//前序遍历为1 2 4 7 3 5 6 8
	//中序遍历为4 7 2 1 5 3 8 6
	//后序遍历输出为7 4 2 5 8 6 3 1
	
	
	/*
			1
		2      3
	4        5   6 
	 7	        8
	 
	 其中4是2的左节点
	 7是4的右节点
	 5是3的左节点
	 6是3的右节点
	 8是6的左节点 
					
	*/ 
	
}





/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector pre,vector vin) {
        if(pre.size()!=vin.size()|| pre.size()<=0||vin.size()<=0 )
        {
            return NULL;
        }
        else
        {
            TreeNode* inRoot=createTree(pre,vin,0,0,vin.size()-1);//用inroot 就过不了
            return inRoot;
        }
    }
    TreeNode* createTree(vector pre,vector vin,int preroot,int vinleft,int vinright)
    {
        int vinroot,rootval;
        rootval=pre[preroot];//根节点的值
         for(int i=vinleft;i<=vinright;i++)
         {
             if(vin[i]==rootval)
             {
                 vinroot=i;
             }
         }
        if(vinleft>vinright) return NULL;
        int leftlen=vinroot-vinleft;//计算的是中序里面从根节点到最左侧的距离 这里千万不能拿先序的根节点来计算
         
        TreeNode *inRoot=new TreeNode(rootval);
            inRoot->left=createTree(pre,vin,preroot+1,vinleft,vinroot-1);
            inRoot->right=createTree(pre,vin,preroot+leftlen+1,vinroot+1,vinright);
        return inRoot;
         
         
         
         
    }
     
     
     
};



你可能感兴趣的:(剑指offer解题报告)