[C++] BFS-based Solution Explained,~99% Time, ~5% Memory
I have to admit that I am still not great in all those tricks you can do with x-order traversals and then rebuild stuff using invariants. But I will get there; 
I have to admit that I am still not great in all those tricks you can do with x-order traversals and then rebuild stuff using invariants. But I will get there; for now, I just wanted to have fun, so I went to solve it my own way, creating an encoding of comma-separated values (similar to how you build trees in LC\'s input fields, just having empty strings instead of writing `"null"` there) on one hand and reading it on the others.\n\nTurned out my solution is still definitely efficient and can solve [a hard problem](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/) without changing a single comma of it (okay, I admit before I set the value of empty nodes to `-1` and now I changed to `INT_MIN` to be compiant with the new rules, but that is about it).\n\nBut let\'s proceed in order:\n\n## Encoding Part\n\nAs usual, edge cases out of the table first: if the tree is empty, we return just an empty string.\n\nIf not, we declare a few variables:\n* `res`, a string initialised with the value of `root->val` converted to string;\n* `len`, to store the length of our queue (more about it in just about one line!), initialised to `1` (since we know at least `root` is a valid node);\n* `q`, a queue of `TreeNode` pointers, that we go and fill in immediately with `root`.\n\nThen we start with our BFS, which will loop as long as `len` is not `0`; inside, with another loop, we will keep removing the first `len` elements in front of the the queue and, for each one of them, we will:\n* assign it to `root` (no need to create a new variable here);\n* add a comma to `res`;\n* if we have `root->left`, then we will:\n\t* add the stringified version of its value to `res`;\n\t* add the node itself to `q`;\n* add another comma to `res`;\n* if we have `root->right`, then we will:\n\t* add the stringified version of its value to `res`;\n\t* add the node itself to `q`.\n\nIf you try to proceed step-by-step, you will see that this will convert a starting tree to a format rather similar to the one used in LC\'s custom inputs, just leaving an empty string where they put `"null"` as mentioned, to save space, and with possibly some extra trailing commas on the last level.\n\nIf you want to test yourself the logic with a non-trivial tree, try to put as a custom input `[100,90,110,80,95,105,115,70,null,null,98,104,106,null,200,60,75,null,99,null,null,null,107,116,201]` and it should give you back `"100,90,110,80,95,105,115,70,,,98,104,106,,200,60,75,,99,,,,107,116,201,,,,,,,,,,,,"`.\n\nOnce we are done, we can return `res` :)\n\n## Decoding Part\n\nSpecularly, first of all away with the edge cases: if the input string `ser` (short for "serialised", but also mirroring `res` above: how cool is that? Yeah, not much, but I am a simple man) is empty, we just return a `NULL` (=empty) tree.\n\nNow, support variables:\n* `len`, similar to the one above, preset to `1` and used for the BFS approach;\n* `nextVal`, where we will store what we read from each bit of serialisation;\n* `root`, initialised with the first value read from the `ser` and our result variable, and `curr`, both `TreeNode` pointers;\n* `q`, a queue of `TreeNode` pointers like the one above, initialised with `root`.\n\nEvery step of reading from the input string will be done using a class variable, `pos`, initialised to `0` and progressively incremented, and using the helper function `readString` that will take one character at a time (or no characters at all, for `NULL` nodes) to compose `res`, that will be then returned after being converted to a number (if not empty) or `INT_MIN` (if empty).\n\nIn our BFS, again same as above, we will loop until `len` is not `0` and internally we will extract at each round the first `len` nodes in front of `q`; I know here I could have just probably kept running until I had nodes in the queue, but I really enjoyed the symmetry of the 2 parts of the solution and I deem it important: elegant code is code that is more easily read, used and maintained.\n\nOr so I like to delude myself.\n\nAnyway, for each extracted node, we will:\n* read from the input string `ser` and assign it to `nextVal`;\n* if `nextVale` is not `INT_MIN`, we will then create a new `TreeNode` with that avalue, add it as a left branch to `curr` and push it into `q`;\n* read again from the input string `s` and assign it to `nextVal`;\n* if `nextVale` is not `INT_MIN`, we will then create a new `TreeNode` with that avalue, add it as a right branch to `curr` and push it into `q`,\n\nRinse and repeat until `q` is empty (`ser` will never be empty before it) and finally you can return `root` :)\n\nThe code:\n\n```cpp\nclass Codec {\npublic:\n    // encoding logic\n    string serialize(TreeNode* root) {\n        // edge case out\n        if (!root) return "";\n        // support variables\n        string res = to_string(root->val);\n        int len = 1;\n        queue<TreeNode*> q;\n        q.push(root);\n\t\t// BFS here!\n        while (len) {\n            while(len--) {\n                // extracting the front of the queue\n                root = q.front();\n                q.pop();\n                res += \',\';\n                if (root->left) {\n                    res += to_string(root->left->val);\n                    // adding the next node only if meaningful - if it has children\n                    q.push(root->left);\n                }\n                res += \',\';\n                if (root->right) {\n                    res += to_string(root->right->val);\n                    // adding the next node only if meaningful - if it has children\n                    q.push(root->right);\n                }\n            }\n            len = q.size();\n        }\n        return res;\n    }\n    \n    // decoding logic\n    int pos = 0;\n    int readString(string &s) {\n        string tmp = "";\n        while(pos < s.size() && s[pos] != \',\') tmp += s[pos++];\n        pos++;\n        return tmp.size() ? stoi(tmp) : INT_MIN;\n    }\n\n    TreeNode* deserialize(string ser) {\n        if (!ser.size()) return NULL;\n        int len = 1, nextVal;\n        TreeNode *root = new TreeNode(readString(ser)), *curr;\n        queue<TreeNode*> q;\n        q.push(root);\n        while (len) {\n            while(len--) {\n                // extracting the front of the queue\n                curr = q.front();\n                q.pop();\n                // adding left and right branches if present to both the tree and the queue\n                nextVal = readString(ser);\n                if (nextVal != INT_MIN) {\n                    curr->left = new TreeNode(nextVal);\n                    q.push(curr->left);\n                }\n                nextVal = readString(ser);\n                if (nextVal != INT_MIN) {\n                    curr->right = new TreeNode(nextVal);\n                    q.push(curr->right);\n                }\n            }\n            len = q.size();\n        }\n        return root;\n    }\n};\n```
['Breadth-First Search', 'C', 'C++']