[LeetCode]problem 114. Flatten Binary Tree to Linked List
来源:互联网 发布:淘宝商家贷款条件 编辑:程序博客网 时间:2024/06/05 20:23
TAG
先序遍历
找先序遍历上一个节点
把二叉树变成一个链表
右左根
顺序与先序相反
题目链接
方法
要把一棵二叉树变为先序遍历结果的链表,而且是由右子树展开。
首先,很直观的想法就是先序遍历,同时记录先序遍历中上一个非空节点,这样只需要访问当前节点时,使上一个节点的右子树指向当前节点即可。但是需要注意的是,常规先序遍历先遍历左子树,所以把前一个节点(父节点)的右孩子设为当前节点后,父节点的右孩子就没有了(还没有被访问呢!)。所以一个很简单的想法就是遍历子节点前交换左右孩子的指针。这样交换后,先遍历右子树(即未交换时的左子树,满足先序遍历),然后下个过程将设置该节点的右子树值,而该右子树已经遍历过了,所以设置后没有什么问题!
以下是递归版本的代码:
void doFlatten(TreeNode *curNode, TreeNode * &parentNode){ using std::swap; if(curNode == nullptr) { return ;} swap(curNode->left, curNode->right); if(parentNode !=nullptr) { parentNode->right = curNode; } parentNode = curNode; doFlatten(curNode->right, parentNode); doFlatten(curNode->left, parentNode); curNode->left = nullptr;}
现在一想,在递归版本,根本没有必要交换左右子树,直接用一个临时变量存储当前节点,在遍历完成后再分别设置右孩子为该临时值,左孩子为空即可。更加直观简单了…不过用非递归的话,似乎就没有那么方便了,交换似乎是必须的?
递归版本的代码10ms运行完成。为非递归版本,能够8ms跑完(见代码部分)。
上述已经算是比较圆满解决了,但是看题解发现一种有点巧妙的想法!
如果我们通过先序遍历,必须记录先序遍历下上一个非空节点,同时为了避免覆盖右子树,还需要交换(或者只需要一个临时指针)。如果我们反序遍历顺序:
先序遍历是: 根 -> 左 -> 右 , 在访问根节点时将上个节点的右孩子设为当前根的值;
如果我们遍历顺序变为: 右 -> 左 -> 根, 那么我们得到的结果与先序遍历的结果是相反的!这样我们就反过来了,不是保存上一个访问的节点,而是保存先序遍历下一个将遇到的节点(此种遍历下上一个访问的节点)。
嗯,这么一想也跟先序是一样的,只是有些惊奇罢了。想想一点也不高级…不过也学到了,就是 先右子树,再左子树,最后根节点,得到预先序遍历相反的序列。
代码
非递归版本。感觉比递归更加简洁:
class Solution {public: void flatten(TreeNode* root) { stack<TreeNode *> s; TreeNode *ptr = root ; TreeNode *parentNode = nullptr; while(ptr != nullptr || !s.empty()) { if(ptr != nullptr) { swap(ptr->left, ptr->right); if(parentNode != nullptr){ parentNode->right = ptr; } s.push(ptr); parentNode = ptr; ptr = ptr->right; } else { // backtracing ptr = s.top(); s.pop(); TreeNode *tmp = ptr->left; ptr->left = nullptr; ptr = tmp; } } }};
问题
不能delete(free)
这个TreeNode节点!之前做递归时,我不想在递归中加入判断上一个节点是否为空的情况,就给加了一个dummy根节点,最后再释放掉,结果就报RE错误了!试了半天,发现把delete一行删除就好使了… 换成malloc+free也同样报错。在释放前把左右指针设为空也不好使… 实在不知道是怎么回事.难道还没有生成析构函数——难道析构是private的?不能吧,这样编译都过不了啊… orz,不明白。
- [LeetCode]problem 114. Flatten Binary Tree to Linked List
- LeetCode: Flatten Binary Tree to Linked List
- LeetCode Flatten Binary Tree to Linked List
- LeetCode: Flatten Binary Tree to Linked List
- [Leetcode] Flatten Binary Tree to Linked List
- [LeetCode] Flatten Binary Tree to Linked List
- Leetcode: Flatten Binary Tree to Linked List
- leetcode Flatten Binary Tree to Linked List
- LeetCode Flatten Binary Tree to Linked List
- LeetCode - Flatten Binary Tree to Linked List
- 【leetcode】Flatten Binary Tree to Linked List
- [LeetCode]Flatten Binary Tree to Linked List
- [Leetcode]Flatten Binary Tree to Linked List
- [leetcode]Flatten Binary Tree to Linked List
- LeetCode-Flatten Binary Tree to Linked List
- [leetcode] Flatten Binary Tree to Linked List
- LeetCode - Flatten Binary Tree to Linked List
- LeetCode:Flatten Binary Tree to Linked List
- margin:auto 与 margin:0 auto 区别
- c++:指向学生类的指针:求最高成绩
- 转载PHP数组浅析
- iOS js oc相互调用(JavaScriptCore)(二)
- DP 0-1背包问题
- [LeetCode]problem 114. Flatten Binary Tree to Linked List
- WebForms UnobtrusiveValidationMode 需要“jquery”ScriptResourceMapping
- 多态概念
- MyBatis-环境配置以及查询
- 【c++程序】句子逆序
- 关于悲观锁和乐观锁
- CodeIgniter学习笔记 Item6--CI中的常规主题
- 消息转换器HttpMessageConverter
- 转载常用PHP函数(数组、字符串、文件、日期、图像)