數據結構之美--樹(01)

1.重建二叉樹

題目:輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回

思路:前序(根左右)遍歷的第一個節點就是根節點,因而咱們在中序(左根右)遍歷中找到該節點,因而該節點就把樹劃分紅了左子樹和右子樹,以後遞歸求解便可

/** * 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)
	{
		auto pre_size = preorder.size();
		auto in_size = inorder.size();

		if (pre_size != in_size || pre_size == 0 || in_size == 0)
			return nullptr;

		return fun(preorder, 0, pre_size - 1, inorder, 0, in_size - 1);
	}
	TreeNode *fun(vector<int> &preorder, int preL, int preR, 
		vector<int> &inorder, int inderL, int inderR)
	{
		if (preL > preR)
			return nullptr;
		TreeNode *root = new TreeNode(preorder[preL]);

		int i = 0;
		for (; i <= inderR; i++)
		{
			if (inorder[i] == preorder[preL])
				break;
		}

		int left_size = i - inderL;
		int right_size = inderR - i;

		root->left = fun(preorder, preL + 1, preL + left_size, 
			inorder, inderL, i - 1);

		root->right = fun(preorder, preL + left_size + 1, preR, 
			inorder, i + 1, inderR);

		return root;
	}
};

4. 序列化二叉樹

題目:實現兩個函數,分別用來序列化和反序列化二叉樹
題解:首先,前序遍歷化爲一個序列! 
反序列化時,第一個就是root,以後前半部分是左子樹,後半部分是右子樹,遇到一個’#'就得回到前面去找其node

class Codec
{
  public:
    // Encodes a tree to a single string.
    string serialize(TreeNode *root)
    {
        if (root == nullptr)
            return "#";
        return to_string(root->val) + "," + serialize(root->left) +","+ serialize(root->right);
    };
    // Decodes your encoded data to tree.
    TreeNode *deserialize(string data)
    {
        return fun(data);
    }

  private:
    TreeNode *fun(string &data)
    {
        if (data == "")
            return nullptr;
        if (data[0] == '#')
        {
            data = data.substr(data.find(',')+1);
            return nullptr;
        }

        size_t idx=0;
        int x = stoi(data,&idx);
         data = data.substr(idx + 1);
        
        TreeNode *root = new TreeNode(x);
        
        root->left = fun(data);
        root->right = fun(data);
        return root;
    }
};

這是最騷的:web

class Codec {
    private:
    TreeNode* _root;
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        _root = root;
        return string();
    }
    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        return _root;
    }
};

3. BST的後序遍歷序列

題目:輸入一個整數數組,判斷該數組是否是某二叉搜索樹的後序遍歷的結果。若是是則輸出Yes,不然輸出No。假設輸入的數組的任意兩個數字都互不相同

後序遍歷(左右根).最後一個節點必定是整個樹的根節點,根據樹與遞歸的關係,泛化而講,他會是的根節點(包括左子樹,右子樹等等).因此咱們的思路就是先找到根,而後判斷前部分(至關於左子樹)是否小於根,後部分(至關於右子樹)是否大於根便可

class Solution
{
  public:
    bool VerifySquenceOfBST(vector<int> sequence)
    {
        int sz = sequence.size();
        if (sz == 0)
            return false;
        return IsBST(sequence, 0, sz - 1);
    }
    //第一部分是左子樹結點的值,它們都比根結點的值小
    bool IsBST(const vector<int> &sequence, int left, int right)
    {
        if (left >= right)
            return true;
        int mid, tp = left;
        int root = sequence.at(right);
        /*先找左子樹*/
        while (tp < right && sequence.at(tp) < root)
        {
            tp++;
        }
        if (tp < right)
        {
            mid = tp;
            //第二部分是右子樹結點的值,它們都比根結點的值大
            // 查找右子樹是否符合要求
            while (tp < right)
            {
                if (sequence.at(tp) < root)
                {
                    return false;
                }
                tp++;
            }
        }
        // 遞歸的判斷左右子樹是否符合要求
        return IsBST(sequence, left, mid - 1) && IsBST(sequence, mid, right - 1);
    }
};
相關文章
相關標籤/搜索