Design an algorithm to encode an N-ary tree into a binary tree and decode the binary tree to get the original N-ary tree. An N-ary tree is a rooted tree in which each node has no more than N children. Similarly, a binary tree is a rooted tree in which each node has no more than 2 children. There is no restriction on how your encode/decode algorithm should work. You just need to ensure that an N-ary tree can be encoded to a binary tree and this binary tree can be decoded to the original N-nary tree structure.
For example, you may encode the following 3-ary
tree to a binary tree in this way:
Note that the above is just an example which might or might not work. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.
Note:
N
is in the range of[1, 1000]
- Do not use class member/global/static variables to store states. Your encode and decode algorithms should be stateless.
這道題讓我們將一棵N叉樹編碼為二叉樹,其實還需要將二叉樹解碼回N叉樹。題目中說了具體的編解碼的方法無所謂,那么就怎么簡單怎么來唄。首先想一下這道題的難點是什么,N叉樹的特點的每個結點最多有N個子結點,而二叉樹的每個結點最多只能有兩個子結點,那么多余的子結點怎么辦,當然只能繼續子結點下繼續累加,就像泡泡龍游戲一樣,一個掛一個的。如何累,得確定一套具體的規則,這樣解碼的時候,反向來一遍就可以了。對於當前結點 root 的N個子結點的處理辦法是,將第一個結點掛到二叉樹的左子結點上,然后將后面的結點依次掛到右子結點,和右子結點的右子結點上,這樣做的好處是,同一層的子結點都掛在右子結點上,而這些子結點自己的子結點都會掛在左子結點上,聽起來很暈是么,那就舉例說明一下吧,就用題目中的例子中的樹好了(注意題目中說只要能把N叉樹編碼成二叉樹,然后再解碼回原N叉樹,並不 care 到底編碼成啥樣的二叉樹)。
N-ary Tree: 1 / | \ 3 2 4 / \ 5 6 Binary Tree: 1 / 3 / \ 5 2 \ \ 6 4
我們可以看出,N叉樹根結點1的第一個子結點3被掛到了二叉樹的左子結點上,同一層的結點2掛到了結點3的右子結點上,同一層的結點4被掛到了結點2的右子結點上。而結點3本身的子結點也按照這個規律,第一個子結點5掛到了結點3的左子結點上,而同一排的結點6掛到了結點5的右子結點上。
對於解碼,也是同樣的規律,先根據根結點值新建一個空的N叉樹結點,由於我們的編碼規律,根結點是一定沒有右子結點的,所以取出左子結點 cur,並且開始循環,如果 cur 結點存在,那么我們對 cur 遞歸調用解碼函數,將返回的結點加入當前N叉樹結點的 children 數組中,然后 cur 再賦值為其右子結點,繼續遞歸調用解碼函數,再加入 children 數組,如此便可將二叉樹還原為之前的N叉樹,參見代碼如下:
class Codec { public: // Encodes an n-ary tree to a binary tree. TreeNode* encode(Node* root) { if (!root) return NULL; TreeNode *res = new TreeNode(root->val); if (!root->children.empty()) { res->left = encode(root->children[0]); } TreeNode *cur = res->left; for (int i = 1; i < root->children.size(); ++i) { cur->right = encode(root->children[i]); cur = cur->right; } return res; } // Decodes your binary tree to an n-ary tree. Node* decode(TreeNode* root) { if (!root) return NULL; Node *res = new Node(root->val, {}); TreeNode *cur = root->left; while (cur) { res->children.push_back(decode(cur)); cur = cur->right; } return res; } };
類似題目:
Serialize and Deserialize N-ary Tree
參考資料:
https://leetcode.com/problems/encode-n-ary-tree-to-binary-tree/