Given a binary tree, flatten it to a linked list in-place.

For example,
Given

         1
/ \
2 5
/ \ \
3 4 6

The flattened tree should look like:

   1
\
2
\
3
\
4
\
5
\
6

click to show hints.

Hints:

If you notice carefully in the flattened tree, each node's right child points to the next node of a pre-order trave

这道题要求把二叉树展开成链表,根据展开后形成的链表的顺序分析出是使用先序遍历,那么只要是数的遍历就有递归和非递归的两种方法来求解,这里我们也用两种方法来求解。首先来看递归版本的,思路是先利用 DFS 的思路找到最左子节点,然后回到其父节点,把其父节点和右子节点断开,将原左子结点连上父节点的右子节点上,然后再把原右子节点连到新右子节点的右子节点上,然后再回到上一父节点做相同操作。代码如下:

解法一:

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

例如,对于下面的二叉树,上述算法的变换的过程如下:

    / \

  / \   \

    / \

    \   \
3
\ \
2
\
3
\
4
\ \

下面再来看非迭代版本的实现,这个方法是从根节点开始出发,先检测其左子结点是否存在,如存在则将根节点和其右子节点断开,将左子结点及其后面所有结构一起连到原右子节点的位置,把原右子节点连到元左子结点最后面的右子节点之后。代码如下:

解法二:

class Solution {
public:
void flatten(TreeNode *root) {
TreeNode *cur = root;
while (cur) {
if (cur->left) {
TreeNode *p = cur->left;
while (p->right) p = p->right;
p->right = cur->right;
cur->right = cur->left;
cur->left = NULL;
}
cur = cur->right;
}
}
};

例如,对于下面的二叉树,上述算法的变换的过程如下:

    / \

  / \   \

    \
2
/ \
3 4
\ \ \ \ \ \ \

前序迭代解法如下:

解法三:

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

此题还可以延伸到用中序,后序,层序的遍历顺序来展开原二叉树,分别又有其对应的递归和非递归的方法,有兴趣的童鞋可以自行实现。

Github 同步地址:

https://github.com/grandyang/leetcode/issues/114

类似题目:

Flatten a Multilevel Doubly Linked List

参考资料:

https://leetcode.com/problems/flatten-binary-tree-to-linked-list/

https://leetcode.com/problems/flatten-binary-tree-to-linked-list/discuss/37182/my-recursive-solution-is-easy-and-clean

https://leetcode.com/problems/flatten-binary-tree-to-linked-list/discuss/36977/my-short-post-order-traversal-java-solution-for-share

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Flatten Binary Tree to Linked List 将二叉树展开成链表的更多相关文章

  1. [LeetCode] 114. Flatten Binary Tree to Linked List 将二叉树展开成链表

    Given a binary tree, flatten it to a linked list in-place. For example,Given 1 / \ 2 5 / \ \ 3 4 6 T ...

  2. [LintCode] Flatten Binary Tree to Linked List 将二叉树展开成链表

    Flatten a binary tree to a fake "linked list" in pre-order traversal. Here we use the righ ...

  3. LeetCode 114| Flatten Binary Tree to Linked List(二叉树转化成链表)

    题目 给定一个二叉树,原地将它展开为链表. 例如,给定二叉树 1 / \ 2 5 / \ \ 3 4 6 将其展开为: 1 \ 2 \ 3 \ 4 \ 5 \ 6 解析 通过递归实现:可以用先序遍历, ...

  4. 114. Flatten Binary Tree to Linked List -- 将二叉树转成链表(in-place单枝树)

    Given a binary tree, flatten it to a linked list in-place. For example,Given 1 / \ 2 5 / \ \ 3 4 6 T ...

  5. 【LeetCode-面试算法经典-Java实现】【114-Flatten Binary Tree to Linked List(二叉树转单链表)】

    [114-Flatten Binary Tree to Linked List(二叉树转单链表)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given a bin ...

  6. Leetcode:Flatten Binary Tree to Linked List 解题报告

    Flatten Binary Tree to Linked List Given a binary tree, flatten it to a linked list in-place. For ex ...

  7. [LeetCode]Flatten Binary Tree to Linked List题解(二叉树)

    Flatten Binary Tree to Linked List: Given a binary tree, flatten it to a linked list in-place. For e ...

  8. LeetCode——Flatten Binary Tree to Linked List

    Given a binary tree, flatten it to a linked list in-place. For example, Given 1 / \ 2 5 / \ \ 3 4 6 ...

  9. [leetcode]Flatten Binary Tree to Linked List @ Python

    原题地址:http://oj.leetcode.com/problems/flatten-binary-tree-to-linked-list/ 题意: Given a binary tree, fl ...

随机推荐

  1. iOS 保存、读取与应用状态

    固化 对于大多数iOS应用,可以将其功能总结为:提供一套界面,帮助用户管理特定的数据.在这一过程中,不同类型的对象要各司其职:模型对象负责保存数据,视图对象负责显示数据,控制器对象负责在模型对象与视图 ...

  2. .Net语言 APP开发平台——Smobiler学习日志:如何实现离线声音文件上传

    最前面的话:Smobiler是一个在VS环境中使用.Net语言来开发APP的开发平台,也许比Xamarin更方便 一.目标样式 我们要实现上图中的效果,需要如下的操作: 1.从工具栏上的"S ...

  3. .net 用户控件ascx.cs注册js脚本代码无效果

    在.net web项目中碰到一个比较奇怪的问题,网上没找到解决方案,先自己mark一下 问题描述: 添加一个用户控件ascx,在后端.cs添加js注册脚本,执行后没有弹出框 注册脚本为: this.P ...

  4. C#开发微信门户及应用(23)-微信小店商品管理接口的封装和测试

    在上篇<C#开发微信门户及应用(22)-微信小店的开发和使用>里面介绍了一些微信小店的基础知识,以及对应的对象模型,本篇继续微信小店的主题,介绍其中API接口的封装和测试使用.微信小店的相 ...

  5. 三大框架之hibernate入门

    hibernate入门   1.orm      hibernate是一个经典的开源的orm[数据访问中间件]框架           ORM( Object Relation Mapping)对象关 ...

  6. CentOS7系统安装及初始化

    1.运行VirtualBox5. 2.安装CentOS7系统. 注意:选择Basic Server类型 安装过程略. 3.修改计算机IP和计算机名. 1)nmtui 1.修改主机名: nmcli ge ...

  7. NFR

    你NFR了吗? NFR,即非功能性需求 (Non -Functional Requirements) ,即系统能够完成所期望的工作的性能与质量.具体包括如下内容: – 效率: 软件实现其功能所需要的计 ...

  8. 在阿里云中编译Linux4.5.0内核 - Ubuntu内核编译教程

    实验环境:Ubnuntu 64位(推荐使用14.04)+Xshell 阿里云现在提供的云服务器很好用的,用来编译内核性能也不错.本文介绍最基本的内核编译方法,为了方便,所有操作均在root用户下进行. ...

  9. MySQL备份锁

    无论逻辑备份还是物理备份,为了获取一致性位点,都强依赖于FTWRL(Flush Table With Read Lock).这个锁杀伤力非常大,因为持有锁的这段时间,整个数据库实质上不能对外提供写服务 ...

  10. 记录 git 常用的操作命令总结

    记录 git 常用的操作命令总结 2016-12-15 16:44:04 作为一名开发者,熟悉使用 git 代码管理工具是一项必备的基本技能.git 相较 SVN 而言,其优点不言而喻.git 的功能 ...