leetcode 关于树的一些题目
2015-06-16 21:06
302 查看
我们知道树的便利最好的方法是递归(写起来简单)
但是也可以用迭代。迭代中当先序遍历时 实际上是用队列是可以实现的,而中序遍历和后序遍历却无法用队列实现,而是需要用到栈,原因在于,我们在遍历一个节点时,并不马上输出它,而是先要去遍历它的左孩子(中序),或者左右孩子(后续)。这就是队列所无法解决的问题。
对于中序遍历,我们可以一直对节点的左子树入栈,也就是说每次入栈,我们都将其左子树遍历完了。等到我们需要出栈的时候,我们会检查栈顶元素是否有右子树,如果有就将右子树及其它的左子树全部全部入栈,弹出节点即可。
而对于后序遍历 则没有办法那么直接,因为后序遍历需要我们在输出本节点之前先输出左子树和右子树,我们在栈顶得到一个元素的时候,没有办法确定这个元素是否已经访问过它的子树了(而中序遍历可以知道的原因是,我们知道当元素出现在栈顶时,它的左子树必须是已经被访问过了)
当然我们也有办法去知道它是否被遍历过,一个非常简单的想法,是为每个树节点设置一个标记位
如果这个节点已经被访问过之后,就输出,否则将左右子树入栈,设计标记位为已经访问过。
本章最后一题:
Binary Tree Maximum Path Sum
Given a binary tree, find the maximum path sum.
The path may start and end at any node in the tree.
For example:
Given the below binary tree,
Return
树的最长路径,按照树的结构,可以写出下面算法,最长路径,
或者 1.与本节点所在的路径相关,此时也有两种情况,一是本节点连接的左右子树一起作为最长的路径,本节点还需要依赖父亲节点构成最长路径
2与本节点无关,
有没有关系只要用max这个函数就可以解决。
但是也可以用迭代。迭代中当先序遍历时 实际上是用队列是可以实现的,而中序遍历和后序遍历却无法用队列实现,而是需要用到栈,原因在于,我们在遍历一个节点时,并不马上输出它,而是先要去遍历它的左孩子(中序),或者左右孩子(后续)。这就是队列所无法解决的问题。
对于中序遍历,我们可以一直对节点的左子树入栈,也就是说每次入栈,我们都将其左子树遍历完了。等到我们需要出栈的时候,我们会检查栈顶元素是否有右子树,如果有就将右子树及其它的左子树全部全部入栈,弹出节点即可。
class Solution { public: vector<int> inorderTraversal(TreeNode *root) { // Start typing your C/C++ solution below // DO NOT write int main() function vector<int> result(0); if (root == NULL) return result; stack<TreeNode*> stk; TreeNode* cur = root; while(cur){ stk.push(cur); cur=cur->left; } while(!stk.empty()){ cur=stk.top(); stk.pop(); result.push_back(cur->val); cur=cur->right; while(cur){ stk.push(cur); cur=cur->left; } } return result; } };
而对于后序遍历 则没有办法那么直接,因为后序遍历需要我们在输出本节点之前先输出左子树和右子树,我们在栈顶得到一个元素的时候,没有办法确定这个元素是否已经访问过它的子树了(而中序遍历可以知道的原因是,我们知道当元素出现在栈顶时,它的左子树必须是已经被访问过了)
当然我们也有办法去知道它是否被遍历过,一个非常简单的想法,是为每个树节点设置一个标记位
如果这个节点已经被访问过之后,就输出,否则将左右子树入栈,设计标记位为已经访问过。
class Solution { public: vector<int> postorderTraversal(TreeNode *root) { vector <int> travel; subpost(travel,root); return travel; } void subpost(vector <int> & travel,TreeNode * root){ if(root==NULL){ return ; } stack <TreeNode *> s; stack <bool>ss; TreeNode * cur; TreeNode * prev=NULL; ss.push(false); s.push(root); cur=root; int count=0; while(!s.empty()){ cur=s.top(); if(!cur->left&&!cur->right){ travel.push_back(cur->val); s.pop(); ss.pop(); continue; } if(ss.top()==true){ travel.push_back(cur->val); s.pop(); ss.pop(); } else{ ss.top()=true; if(cur->right){ s.push(cur->right); ss.push(false); } if(cur->left){ s.push(cur->left); ss.push(false); } } } } };
本章最后一题:
Binary Tree Maximum Path Sum
Given a binary tree, find the maximum path sum.
The path may start and end at any node in the tree.
For example:
Given the below binary tree,
1 / \ 2 3
Return
6.
树的最长路径,按照树的结构,可以写出下面算法,最长路径,
或者 1.与本节点所在的路径相关,此时也有两种情况,一是本节点连接的左右子树一起作为最长的路径,本节点还需要依赖父亲节点构成最长路径
2与本节点无关,
有没有关系只要用max这个函数就可以解决。
class Solution { public: int maxPathSum(TreeNode *root) { int chain=0,value=0,maxx=root->val; submax(root,chain,maxx); return maxx; } void submax(TreeNode *node,int &chain,int &maxx){ int chainl=0,chainr=0; if(node==NULL){ return; } submax(node->left,chainl,maxx); submax(node->right,chainr,maxx); maxx=max(chainl+chainr+node->val,maxx); chain=max(chainl,chainr); chain=max(0,chain+node->val); } };
相关文章推荐
- h5关于选择器以及class的小加强
- 服务器 交换分区(Swap)
- Linux系统命令缩写
- yum的错误
- UVa 10622 - Perfect P-th Powers(数论)
- C++标准库之Unities-笔记2
- 新的一天 新的征程
- bash: service: command not found 错误的解决方法
- RedHat5.5配置
- 程序员的级别
- C++ extern/static/const
- 数据库原理与设计课后作业——习题九
- Android事件分发机制完全解析,带你从源码的角度彻底理解(上)
- 配置vsftpd
- Java实现辩论赛计时
- 封装一个类搞定90%安卓客户端与服务器端交互
- Android基于socket的群聊程序
- [FlashDevelop] 001.FlashDevelop + LayaFlash环境搭建
- linux中vsftp修改默认路径
- vsftpd 配置:chroot_local_user与chroot_list_enable详解