4.重建二叉树(做第二遍时感觉仍有有难度,第三次做还是要看一下思路才行)

重建二叉树

题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
我没有按照书上的做法来解,而是采用long型指针来存储地址,虽然很绕,但是可以熟悉指针的使用。牛客网使用的是64位编译器,故不能用int数组存地址,而要使用long型数组。
<pre name="code" class="cpp">// 4.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <vector>

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<int> pre, vector<int> in) {
		if (pre.size() <= 0 || in.size() <= 0) return NULL;
		if (pre.size() != in.size()) return NULL;

		int length = pre.size(); // 获得数组的长度

		long* pPre = new long[length];
		int i = 0;
		for (vector<int>::iterator iter = pre.begin(); iter != pre.end(); iter++){
			pPre[i] = (long)&(*iter);// *iter取迭代器中的内容,&(*iter)取该内容的地址,(long)&(*iter)把地址转化为long型
			i++;
		}

		long* pIn = new long[length]; // 动态分配数组内存
		i = 0;
		for (vector<int>::iterator iter = in.begin(); iter != in.end(); iter++){
			pIn[i] = (long)&(*iter);
			i++;
		}

		TreeNode* root = ConstructCore(pPre, pPre + length - 1, pIn, pIn + length - 1);
		// 释放堆上的内存,防止内存泄漏,并清空指针
		delete[] pPre;
		pPre = NULL;
		delete[] pIn;
		pIn = NULL;
		return root;
	}
private:
	TreeNode* ConstructCore(long* pPreStart, long* pPreEnd, long* pInStart, long* pInEnd){
		// 构建根节点
		long rootValue = *(long*)pPreStart[0];
		TreeNode* root = new TreeNode(rootValue);
		root->left = root->right = NULL;

		// 判断是否为递归的退出条件:前序是否到头、中序是否到头、前序与中序是否重合
		if (pPreStart == pPreEnd || pInStart == pInEnd || pPreStart == pInStart){
			return root;
		}

		// 在中序数组中找到根节点的位置
		long* rootPosi = pInStart;
		while (rootPosi <= pInEnd && *(long*)rootPosi[0] != rootValue){
			rootPosi++;
		}
		// 检验是否在中序数组中找到根节点
		if (rootPosi == pInEnd && *(long*)rootPosi[0] != rootValue){ 
			// *(long*)rootPosi与*(long*)rootPosi[0]意义完全不同,*(long*)rootPosi是把数组的第一个元素到最后一个元素看成整体解除指针引用
			//throw new exception("not found!");
			return NULL;
		}

		// 中序数组中根节点据数组头部的距离
		long leftLength = rootPosi - pInStart;

		// 构建左子树的四个实参
		long* pNewPreStartLeft = pPreStart + 1;
		long* pNewPreEndLeft = pPreStart + leftLength;
		long* pNewInStartLeft = pInStart;
		long* pNewInEndLeft = pInStart + leftLength - 1;

		// 构建右子树的四个实参
		long* pNewPreStartRight = pPreStart + leftLength + 1;
		long* pNewPreEndRight = pPreEnd;
		long* pNewInStartRight = rootPosi + 1;
		long* pNewInEndRigth = pInEnd;
		if (leftLength > 0){
			root->left = ConstructCore(pNewPreStartLeft, pNewPreEndLeft, pNewInStartLeft, pNewInEndLeft);
		}
		if (leftLength < pPreEnd - pPreStart){
			root->right = ConstructCore(pNewPreStartRight, pNewPreEndRight, pNewInStartRight, pNewInEndRigth);
		}
		return root;
	}
};
int _tmain(int argc, _TCHAR* argv[])
{
	int arrPre[] = { 1, 2, 4, 7, 3, 5, 6, 8 };
	int arrIn[] = { 4, 7, 2, 1, 5, 3, 8, 6 };
	vector<int> pre(arrPre, arrPre + 8);
	vector<int> in(arrIn, arrIn + 8);

	Solution s;
	TreeNode* result = s.reConstructBinaryTree(pre, in);
	system("pause");
	return 0;
}

第二次做:
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
	struct TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> in) {
        if ( pre.empty() || in.empty() || pre.size() != in.size() ) return NULL ;
        
        int length = pre.size() ;
        
        TreeNode* root = new TreeNode( pre[0] ) ;
        
        int rootVal = pre[0] ;
        int mid = 0;
        for ( ; in[mid] != rootVal; ++ mid ) {
            if ( mid > length) return NULL ;
        }
        
        vector<int> pre_left ;
        vector<int> in_left ;
        for ( int i = 0; i < mid; ++ i ) {
            pre_left.push_back( pre[i + 1] ) ;
            in_left.push_back( in[i] ) ;
        }
        
        vector<int> pre_right ;
        vector<int> in_right ;
        for ( int i = mid + 1; i < length; ++ i ) {
            pre_right.push_back( pre[i] ) ;
            in_right.push_back( in[i] ) ;
        }
        
        root -> left = reConstructBinaryTree( pre_left, in_left ) ;
        root -> right = reConstructBinaryTree( pre_right, in_right ) ;
        
        return root ;
	}
};

第三次做:
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in) {
		if ( pre.empty() || in.empty() || pre.size() != in.size() ) return NULL ;
        
        TreeNode* root = new TreeNode( pre[0] ) ;
        
        int rootVal = pre[ 0 ] ;
        int mid = 0 ;
        int length = pre.size() ;
        
        for ( ; in[mid] != rootVal; ++ mid ) {
           // if ( mid > length ) return NULL ;
        }
        
        vector<int> pre_left ;
        vector<int> in_left ;
        for ( int i = 0; i < mid; ++ i ) {
            pre_left.push_back( pre[i + 1] ) ;
            in_left.push_back( in[i] ) ;
        }
        
        vector<int> pre_right ;
        vector<int> in_right ;
        for ( int i = mid + 1; i < length; ++ i ) {
            pre_right.push_back( pre[i] ) ;
            in_right.push_back( in[i] ) ;
        }
        
        root->left = reConstructBinaryTree( pre_left, in_left ) ;
        root->right = reConstructBinaryTree( pre_right, in_right ) ;
        
        return root ;
    }
};


 
  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值