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

思路:

用先序遍历,得到的是从小到大的顺序。把先序遍历变形一下:

void flatten(TreeNode* root) {
if(NULL == root) return;
vector<TreeNode *> v;
v.push_back(root);
TreeNode * pCur = NULL;
TreeNode * p = NULL; while(!v.empty())
{
pCur = p = v.back();
while(NULL != p->left) //向左移动时只要把当前指针移动即可,因为是按照从小大的顺序的
{
v.push_back(p->left);
pCur = p = p->left;
} while(!v.empty() && (p = v.back()->right) == NULL) //找到下一个要处理的元素,一定是一个右子树
v.pop_back();
if(!v.empty())
v.pop_back(); if(p != NULL) //把待处理的右子树连在当前已经铺平的数的左子树上
{
v.push_back(p);
pCur->left = p;
}
} p = root;
while(p != NULL) //镜像,全部转移到右子树上
{
p->right = p->left;
p->left = NULL;
p = p->right;
}
}

我发现,我太依赖非递归了,其实有的时候用递归更好。比如大神的版本:

private TreeNode prev = null;

public void flatten(TreeNode root) {
if (root == null)
return;
flatten(root.right);
flatten(root.left);
root.right = prev;
root.left = null;
prev = root;
}

先把右子树放平,再把左子树放平。因为每次都先处理右子树,所以prev是数值从大到小的一个记录,每次prev都是恰比当前根节点大一点的那个指针的位置。(不大好理解)

下面这个,跟上面的思路很像,但是会容易理解很多:

public void flatten(TreeNode root) {
if (root == null) return; TreeNode left = root.left;
TreeNode right = root.right; root.left = null; flatten(left);
flatten(right); root.right = left;
TreeNode cur = root;
while (cur.right != null) cur = cur.right;
cur.right = right;
}

也是先铺平右子树,再铺平左子树。一定是右子树的值大于左子树,所以先把左子树连接到根节点右侧,再把右子树连在后面。 这个代码平铺左右子树的顺序没限制。反过来也行。

上面思路的非递归版本: 也是需要想半天才能看懂的。每次先把紧接着子树连好,其他代码都是从叶节点开始连接,这个是从根节点开始的。

public void flatten(TreeNode root) {
if (root == null) return;
Stack<TreeNode> stk = new Stack<TreeNode>();
stk.push(root);
while (!stk.isEmpty()){
TreeNode curr = stk.pop();
if (curr.right!=null)
stk.push(curr.right);
if (curr.left!=null)
stk.push(curr.left);
if (!stk.isEmpty())
curr.right = stk.peek();
curr.left = null; // dont forget this!!
}
}

【leetcode】Flatten Binary Tree to Linked List (middle)的更多相关文章

  1. 【LeetCode】Flatten Binary Tree to Linked List

    随笔一记,留做重温! Flatten Binary Tree to Linked List Given a binary tree, flatten it to a linked list in-pl ...

  2. 【树】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 ...

  3. 【LeetCode】968. Binary Tree Cameras 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  4. Leetcode 之Flatten Binary Tree to Linked List(50)

    将左子树接到右子树之前,递归解决 void flatten(TreeNode *root) { if (root == nullptr)return; flatten(root->left); ...

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

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

  6. 【Leetcode】【Medium】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 ...

  7. 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 ...

  8. 【LeetCode】563. Binary Tree Tilt 解题报告(Java & Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 Java解法 Python解法 日期 题目地址:ht ...

  9. 【LeetCode】257. Binary Tree Paths 解题报告(java & python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 迭代 日期 题目地址:https://leet ...

随机推荐

  1. 【CISP笔记】安全漏洞与恶意代码(2)

    恶意代码自我保护 进程保护 进程守护 超级权限 检测对抗 反动态调试 反静态调试 恶意代码检测技术 特征码扫描 沙箱技术 行为检测 恶意代码分析技术 静态分析 需要实际执行恶意代码,它通过对其二进制文 ...

  2. 阿里云Nginx绑定多个域名的方法

    nginx绑定多个域名,可通过把多个域名规则写一个配置文件里实现,也可通过分别建立多个域名配置文件实现,一般为了管理方便,建议每个域名建一个文件,有些同类域名也可写在一个总的配置文件里. 一.每个域名 ...

  3. 升级xcode7.0 第三方库不能用的解决方法(bitcode是什么鬼?)

    升级完xcode,真机运行发现报错,第三方库错误,微信SDK,高德SDK都报错,如下: ‘/Users/**/Framework/SDKs/PolymerPay/Library/mobStat/lib ...

  4. ScriptManager与UpdatePanel总结

    1.From http://www.cnblogs.com/Tim-Seven/archive/2011/02/11/1952409.html Ajax Extensions 2.ScriptMana ...

  5. Linq查询操作语句学习

    对于一个集合,我们通常会用foreach或者for循环来判断查找里面的元素. 但这种方法通常会看起来比较复杂,我们可以使用linq. Linq允许编写C#代码以查询数据库相同的方式操作内存数据(写法类 ...

  6. cocoapods pod install 安装报错 is not used in any concrete target

    低版本的cocoa pods在编写Podfile文件时这样写就可以了 platform :ios, '8.0'pod 'AFNetworking' 高版本的cocoa pods在编写Podfile文件 ...

  7. springmvc之自定义注解(annotation)

    参考:日志处理 三:Filter+自定义注解实现 系统日志跟踪功能 1.项目结构 2.pom.xml,添加需要依赖 <project xmlns="http://maven.apach ...

  8. sql种类

  9. HDU 4930 Fighting the Landlords(模拟)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4930 解题报告:斗地主,加了一个四张可以带两张不一样的牌,也可以带一对,判断打出一手牌之后,如果对手没 ...

  10. 学习Node.js笔记(一)

    一.什么是Node.js 1.1.Node.js是什么 Node.js是用来编写高性能网络服务器的JavaScript工具包 Node.js 是一个基于Chrome JavaScript 运行时建立的 ...