/** * 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; } };
題目:實現兩個函數,分別用來序列化和反序列化二叉樹
題解:首先,前序遍歷化爲一個序列!
反序列化時,第一個就是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; } };
整個樹
的根節點,根據樹與遞歸
的關係,泛化而講,他會是樹
的根節點(包括左子樹,右子樹等等).因此咱們的思路就是先找到根,而後判斷前部分(至關於左子樹)是否小於根,後部分(至關於右子樹)是否大於根
便可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); } };