114. 二叉樹展開為連結串列

ouyangxx發表於2024-11-15
  1. 題目連結

  2. 解題思路:

    • 對於這類遞迴問題,採用「宏觀」思考模式。
    • 對於任意一個節點A,左子樹先「展開為連結串列」,右子樹再「展開為連結串列」,然後A節點,將左子樹的結果,和右子樹的結果,「串在一起」即可。
    • 左子樹展開為連結串列,所以要返回兩個節點,一個是連結串列的頭,然後是連結串列的尾。
  3. 程式碼

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
     * };
     */
    class Solution {
    public:
        // 將head展開成連結串列
        pair<TreeNode*, TreeNode*> process(TreeNode *head) {
            if (head == nullptr) {
                return {nullptr, nullptr};
            }
            TreeNode *left_head = nullptr;     // 左連結串列的頭
            TreeNode *left_tail = nullptr;     // 左連結串列的尾
            TreeNode *right_head = nullptr;    // 右連結串列的頭
            TreeNode *right_tail = nullptr;    // 右連結串列的尾
            auto left_res = process(head->left);
            auto right_res = process(head->right);
            left_head = left_res.first;
            left_tail = left_res.second;
            right_head = right_res.first;
            right_tail = right_res.second;
            TreeNode *cur_head = head;
            TreeNode *cur_tail = head;
            if (left_head != nullptr) {
                cur_tail->right = left_head;
                cur_tail = left_tail;
                head->left = nullptr;   // 不要忘記這一句
            }
            if (right_head != nullptr) {
                cur_tail->right = right_head;
                cur_tail = right_tail;
            }
            
            return {cur_head, cur_tail};
        }
    
        void flatten(TreeNode* root) {
            process(root);
        }
    };
    

相關文章