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链接...又不知道怎么取消, 只能用``包起来了.

最新文章

  1. 30分钟带你快速入门MySQL教程
  2. 【STL】重载运算符
  3. [3D跑酷] GUIManager UI管理
  4. 学习KMP算法
  5. QT 的信号与槽机制介绍
  6. C语言文件操作解析(五)之EOF解析(转载)
  7. Mysql联合查询UNION和UNION ALL的使用介绍
  8. .htaccess Rewrite apache重写和配置
  9. CSharp设计模式读书笔记(9):组合模式(学习难度:★★★☆☆,使用频率:★★★★☆)
  10. javascript ajax 脚本跨域调用全解析
  11. BOGEER博格尔YT-813码表使用说明书 (我的是YT-823)
  12. 数位dp——hud3652
  13. c++11线程池
  14. PHP设计模式注意点
  15. Python类的构成元素
  16. mongodb初始化并使用node.js实现mongodb操作封装
  17. 采用jquery同django实现ajax通信
  18. UITableView _endCellAnimationsWithContext崩溃
  19. Android 使用zxing生成二维码的方法
  20. C#编译和运行原理

热门文章

  1. postgresql 字符串拼接&quot;||“的使用
  2. C#做的一个加密/解密的类
  3. C#微信公众号开发 -- (一)开发之前的准备
  4. WildFly 9.0.2+mod_cluster-1.3.1 集群配置
  5. 学习笔记_Java_day13_JSTL标签库(1、2、3、4、5、6、7、8)
  6. ios专题 -KVO , KVC
  7. VMware Workstation不能启用虚拟设备floppy0由于灭有相应的有效设备在主机上. 你要尝试在每次打开虚拟机电源时连接此虚拟设备?
  8. 我爆一个托 QQ305242038 电话 18782169971
  9. mysql学习笔记2
  10. [翻译]ASP.NET Web API 2入门