zoukankan      html  css  js  c++  java
  • Flatten Binary Tree to Linked List (LeetCode #114 Medium)(LintCode #453 Easy)

    114. Flatten Binary Tree to Linked List (Medium)
    453. Flatten Binary Tree to Linked List (Easy)
    解法1: 用stack.

    class Solution {
    public:
        void flatten(TreeNode *root) {
        	if(!root) return;
        	TreeNode *pnode = NULL;
        	stack<TreeNode*> s;
        	s.push(root);
        	while(!s.empty()){
        		root = s.top(); s.pop();
        		if(pnode){
        			pnode->left = NULL;
        			pnode->right = root;
        		}
        		if(root->right) s.push(root->right);
        		if(root->left) s.push(root->left);
        		pnode = root;
        	}
        	pnode->left = pnode->right = NULL;
        }
    };
    

    解法2: 递归

    class Solution {
    private:
        void _flatten(TreeNode *root, TreeNode **ph, TreeNode **pt) {
            if (!root) {
                *ph = *pt = NULL;
                return;
            }
            TreeNode *h1, *t1, *h2, *t2;
            _flatten(root->left, &h1, &t1);
            _flatten(root->right, &h2, &t2);
            root->left = NULL;
            *ph = *pt = root;
            if (h1) {
                root->right = h1;
                *pt = t1;
                if (h2) {
                    t1->right = h2;
                    *pt = t2;
                }
            } else if (h2) {
                root->right = h2;
                *pt = t2;
            }
        }
    public:
        void flatten(TreeNode *root) {
            TreeNode *h, *t;
            _flatten(root, &h, &t);
        }
    };
    

    ph其实一定指向root, 所以可以省略. 简化为一下代码:

    class Solution {
    private:
        void _flatten(TreeNode *root, TreeNode **ptail) {
            if (!root) {
                *ptail = NULL;
                return;
            }
            TreeNode *t1, *t2;
            _flatten(root->left, &t1);
            _flatten(root->right, &t2);
            if (t1) {
                t1->right = root->right;
                root->right = root->left;
                root->left = NULL;
            }
            *ptail = t2 ? t2 : (t1 ? t1 : root);
        }
    public:
        void flatten(TreeNode *root) {
            TreeNode *t;
            _flatten(root, &t);
        }
    };
    

    解法3: @Netario36

    假设flatten函数已经可以以前序遍历完成flatten的任务, 且flatten(root->left)flatten(root->right)已完成, 那么接下来要做的操作就是:
    flatten(root->left)后该链表的最后一个节点是tail.
    那么

    tail->right = root->right;
    root->right = tail;
    root->left = NULL;
    

    就可以把root节点, root->left的flatten子树, 和root->right的flatten子树串起来.

    这代码看起来简洁, 但是把左子树处理完并插入到rootroot->right之间后, 要处理插入前的root->right子树需要递归N次, 其中Nroot->left子树节点数. 也就是说, 有很多不必要的递归.

    //@Netario36
    class Solution {
    private:
        TreeNode *tail;
    public:
        void flatten(TreeNode *root) {
            if (!root) return;
            if (root->left) {
                flatten(root->left);
                tail->right = root->right;
                root->right = root->left;
                root->left = NULL;
            }
            tail = root;
            flatten(root->right);
        }
    };
    

    基于@Netario36的版本我写了一个前序遍历结构更明显, 没有无用的递归的版本.

    class Solution {
    private:
        TreeNode *tail;
    public:
        void flatten(TreeNode *root) {
            if (!root) return;
            tail = root;
            if (root->left) {
                flatten(root->left);
                tail->right = root->right;
                root->right = root->left;
                root->left = NULL;
            }
            flatten(tail->right);
        }
    };
    

    解法4: @versavitality

    参数rightRootroot的右兄弟节点, 返回值为root子树与rightRoot子树flatten之后的根节点.

    TreeNode *right = _flatten(root->right, rightRoot);root->right子树与rightRoot子树flatten到一起.

    root->right = _flatten(root->left, right);root->left子树与上一步的结果flatten到一起.

    // @versavitality
    class Solution {
    private:
        TreeNode* _flatten(TreeNode *root, TreeNode *rightRoot) {
            if (!root) return rightRoot;
            TreeNode *right = _flatten(root->right, rightRoot);
            root->right = _flatten(root->left, right);
            root->left = NULL;
            return root;
        }
    public:
        void flatten(TreeNode *root) {
            _flatten(root, NULL);
        }
    };
    

    蛋疼的博客园, 有@字符会翻译成mailto链接...又不知道怎么取消, 只能用``包起来了.

  • 相关阅读:
    poj 1523 SPF (无向图 的 割点)
    codeforces Walking in the Rain (dp 水题 线性 dp)
    GaleShapley算法
    hdu 1087 Super Jumping! Jumping! Jumping! (最大 上升子序列 线性 dp)
    poj 3694 Network (无向图的 割边 lca )
    codeforces To Add or Not to Add (排序 + 优化)
    hdu 3996 Gold Mine ( 最大权闭合图 )
    转:WINFORM多线程编程
    C#串口serialPort操作
    用C# 根据 JSC100 V5.0读写器通讯协议 编写读卡器API
  • 原文地址:https://www.cnblogs.com/7z7chn/p/5081415.html
Copyright © 2011-2022 走看看