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. 大熊君大话NodeJS之------FS文件模块

    一,开篇分析 文件系统模块是一个简单包装的标准 POSIX 文件 I/O 操作方法集.可以通过调用 require("fs") 来获取该模块.文件系统模块中的所有方法均有异步和同步 ...

  2. 包介绍 - Fluent Validation (用于验证)

    Install-Package FluentValidation 如果你使用MVC5 可以使用下面的包 Install-Package FluentValidation.MVC5 例子: public ...

  3. eclipse无法自动识别出svn项目

    因为重新安装了svn插件,重启后发现原来的svn项目无法自动识别出来,连Team->Share Project都没有,而本地用tortoiseSvn是可以正常操作的. 后来我把项目删除然后重新导 ...

  4. 2015多校1006.First One

    First One Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total ...

  5. iOS开发——UI进阶篇(八)pickerView简单使用,通过storyboard加载控制器,注册界面,通过xib创建控制器,控制器的view创建,导航控制器的基本使用

    一.pickerView简单使用 1.UIPickerViewDataSource 这两个方法必须实现 // 返回有多少列 - (NSInteger)numberOfComponentsInPicke ...

  6. js循环添加事件的问题

    1.需求 给下面每个按钮增加事件 <ul id="list"> <li>按钮1</li> <li>按钮2</li> &l ...

  7. CCF 模拟E DFS深搜

    http://115.28.138.223:81/view.page?opid=5 这道题问的很怪. 起点DFS,每一个点还要DFS一次,统计不能到终点的个数 数据量不大这样做也能AC #includ ...

  8. Java abstract

    abstract修饰符可以修饰类和方法. (1)abstract修饰类,会使这个类成为一个抽象类,这个类将不能生成对象实例,但可以做为对象变量声明的类型,也就是编译时类型.抽象类就相当于一类的半成品, ...

  9. tornado 非阻塞方法

    http://sebastiandahlgren.se/2014/06/27/running-a-method-as-a-background-thread-in-python/

  10. openstacksdk enable logging

    http://git.openstack.org/cgit/openstack/python-openstacksdk/tree/doc/source/users/guides/logging.rst