剑指 Offer 07. 重建二叉树 —— 递归分治、迭代

解题思路1

前序遍历的形式:

[ 根节点, [左子树的前序遍历结果], [右子树的前序遍历结果] ]

中序遍历的形式:

[ [左子树的中序遍历结果], 根节点, [右子树的中序遍历结果] ]

所以可以分治的求解该问题,难点是确定分治地边界:

  1. 对前序后中序分别分治,分别传入这两个遍历的左边界和右边界,直到为空结点返回NULL。
  2. 对每一次分治,前序遍历最左边结点的值是根结点。
  3. 根据上一步根结点的值,遍历中序序列,获得根结点在中序遍历的下标,获得左子树的长度,然后就可以进行下一轮分治。

代码1

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* buildSubTree(vector<int>& preorder, vector<int>& inorder,int preLeft,int preRight,int inLeft,int inRight){
        TreeNode* returnNode=new TreeNode;
        if(preRight-preLeft<0)
            return NULL;
        for(int i = inLeft;i<=inRight;i++){
            if(preorder[preLeft]==inorder[i]){
                returnNode->val=inorder[i];
                returnNode->left=buildSubTree(preorder,inorder,preLeft+1,preLeft+i-inLeft,inLeft,i-1);
                returnNode->right=buildSubTree(preorder,inorder,preLeft+i-inLeft+1,preRight,i+1,inRight);
                break;
            }
        }
        return returnNode;
        
    }

    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        return buildSubTree(preorder,inorder,0,preorder.size()-1,0,inorder.size()-1);
    }
};

解题思路2

官方更加巧妙地做法:代码中的if块是用前序数组一直构建左子树,如果碰到了inorder[inorderIndex],表示到了左下角,这时就需要往上走并处理右子树,也就是while代码块。

class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if (!preorder.size()) {
            return nullptr;
        }
        TreeNode* root = new TreeNode(preorder[0]);
        stack<TreeNode*> stk;
        stk.push(root);
        int inorderIndex = 0;
        for (int i = 1; i < preorder.size(); ++i) {
            int preorderVal = preorder[i];
            TreeNode* node = stk.top();
            if (node->val != inorder[inorderIndex]) {
                node->left = new TreeNode(preorderVal);
                stk.push(node->left);
            }
            else {
                while (!stk.empty() && stk.top()->val == inorder[inorderIndex]) {
                    node = stk.top();
                    stk.pop();
                    ++inorderIndex;
                }
                node->right = new TreeNode(preorderVal);
                stk.push(node->right);
            }
        }
        return root;
    }
};

解法二来源:
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/solution/mian-shi-ti-07-zhong-jian-er-cha-shu-by-leetcode-s/
来源:力扣(LeetCode)

你可能感兴趣的:(数据结构与算法,c++,分治,递归)