構造二叉樹

不妨不妨,來日方長發表於2020-12-14

 

 

 

/**
 * 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* buildTree(vector<int>& preorder, vector<int>& inorder) {
        //要先明白,構造一顆二叉樹,首先你得構造出根節點吧,然後你再去構造左右子節點
        //根節點簡單,就是前序遍歷的第一個元素,很容易能夠構造
        //關鍵是你要構造左右子節點以及往下的,你得知道哪些元素是左子樹哪些是右子樹的,這就需要通過中序序列和已知的根節點的值來確定,這是中序的特性
        return build(preorder, 0, preorder.size()-1, inorder, 0, inorder.size()-1);
    }
    TreeNode* build(vector<int> preorder, int prestart, int preend, vector<int> inorder, int instart, int inend)
    {
        if(prestart > preend)
            return nullptr;
        //先儲存根節點的值,找到中序序列中根節點的位置
        int rootval = preorder.at(prestart);
        int index = 0;
        for(int i=instart;i<=inend;i++)
        {
            if(inorder.at(i) == rootval)
            {
                index = i;
                break;
            }
        }
        //以上找到了中序序列中根節點的位置index
        int leftSize = index - instart;//得到左子樹節點的個數,因為要分開前序遍歷序列
        //先構造根節點
        TreeNode* root = new TreeNode(rootval);
        //遞迴構造
        root->left = build(preorder, prestart+1, index+leftSize, inorder, instart, index-1);
        root->right = build(preorder, prestart+leftSize+1, preend, inorder, index+1, inend);
        return root;
    }
};

 

 

 

/**
 * 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* buildTree(vector<int>& inorder, vector<int>& postorder) {
        //後序和中序跟前一個一樣的道理,還是應該先構造頭結點,然後遞迴構造左右子樹
        //需要新建一個函式進行陣列起止位置控制,別的也沒什麼
        //後序最後一個是根節點的值
        return build(inorder, 0, inorder.size()-1, postorder, 0, postorder.size()-1);
    }
    TreeNode* build(vector<int>& inorder, int inStart, int inEnd, vector<int>& postorder, int postStart, int postEnd)
    {
        //base case
        if(inStart > inEnd)
            return nullptr;
        //先儲存根節點的值
        int rootVal = postorder.at(postEnd);
        int index = 0;//記錄中序序列中根節點的位置
        for(int i=inStart;i<=inEnd;i++)
        {
            if(inorder.at(i) == rootVal)
            {
                index = i;
                break;
            }
        }
        int leftSize = index - inStart;
        //構造根節點
        TreeNode* root = new TreeNode(rootVal);
        //遞迴構造左右子樹
        root->left = build(inorder, inStart, index-1, postorder, postStart, postStart+leftSize-1);
        root->right = build(inorder, index+1, inEnd, postorder, postStart+leftSize, postEnd-1);
        return root;
    }
};

 

 

 

/**
 * 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* constructMaximumBinaryTree(vector<int>& nums) {
        //肯定是需要先知道這個最大值,構造根節點,然後遞迴的構造左右子樹,採用前序遍歷框架
        //需要知道子陣列,所以函式的引數不夠,需要自己建構函式,傳入陣列、子陣列頭尾下標
        return build(nums, 0, nums.size()-1);
    }
    TreeNode* build(vector<int>& nums, int lo, int hi)
    {
        if(lo > hi)
            return nullptr;
            
        /*下面這一段是求最大值和最大值索引的,時間複雜度為O(n)*/
        int max_num = nums.at(0);
        int index = 0;
        for(int i=0;i<=hi;i++)
        {
            if(max_num < nums.at(i))
            {
                max_num = nums.at(i);
                index = i;
            }
        }
        /*****************************/

        TreeNode* head = new TreeNode(max_num);
        head->left = build(nums, 0, index);
        head->right = build(nums, index+1, hi);
        return head;
    }
};

 

相關文章