二叉树常见 oj 题(持续更新中)
一:根据二叉树创建字符串
题目介绍:(题目链接)
代码:
思路:
利用的是前序遍历
注意:
左子树和右子树的判断条件 : 1. if(root->left || root -> right) (假如左子树或者右子树不为空,则执行左) 2. if(root->right) (只有当右子树不为空时,执行右分支)
to_string 的利用
void treecopy(TreeNode* root,string& str) (传引用减少构造)
二:二叉树层序遍历
题目描述:(题目链接)
方法一:
思路:
记录当前层数的个数, 一层一层的遍历
利用了队列先进先出的特性
注意事项:
注意队列函数的使用 : q.front() 取出队头的数据
q,back() 取队尾的数据(需要注意是的栈只能取队尾的数据,不能取对头的)
注意 for 循环的使用和 numsize 的更新,for(int i=0;i<numsize;i++), numsize = q.size();
方法二:
三:二叉树的层序遍历 II
题目描述: (题目链接)
代码:
思路:
reverse 一下就得到了
四:二叉树的最近公共祖先
题目描述: 题目链接
方法一:
思路:
逻辑:找到第一个祖先, 有一个节点在祖先的左,有一个节点在祖先的右
.时间复杂度:N*N 算最坏的情况(第一次 findN,第二次 find N-1......),因为 find 的时间复杂度是 O(N)
注意:
bool IsLeftp=!IsRightp;bool IsLeftq=!IsRightq;取反可以就不用再去递归左树了
方法二:
思路:
找到 p,q 的路径
他们两个路径的交点就是共同祖先
两个栈交点的问题 可以理解为 链表交点问题来解决
时间复杂度为 O(N)
注意:
主要是 findpath 函数的实现,主要流程为:
先将 root 入进栈,再判断 root 是否为 P,为 p 则找到了,return true
再判断左子树和右子树, if(findpath(root->left,st,p)) 假如左树找到了,则 return true
假如左右子树都没找到,则 pop 出栈顶的元素
五:二叉树的前中后序遍历(非递归版)
前序
方法一:
通用法,前后中序都基于此思路
思路:
先将左子树入栈,边入边 push_back
左边入完了,再将本节点 pop,入右树
注意:
注意判断条件: while(cur || !st.empty()) ,当本节点不为空或者栈不为空的时候,进循环
TreeNode* tem= st.top(); //先将栈顶节点 pop 掉,因为已经 push_back 了 st.pop();cur = tem->right; //左数完了,再去入右树
方法二:
简洁法
中序
与前序不同的是 v.push_back(tem->val);的时机
后序
方法一:
将前序的结果反转即可得到后序的结果
方法二:
思路:
先入左数
再取栈顶元素
判断,假如(栈顶的右子树为空,或者 右子树为之前访问过的节点),就 push_back,再 pop,更新 prev= 栈顶的元素
如果假如不成立,则再取栈顶的左树去找
注意:
注意 if(top->right == nullptr || top->right == prev) 判断条件
六:二叉搜索树与双向链表
题目描述:题目链接
代码:
思路:
利用中序遍历链接整颗树
用一个 prev 指针指向前一个被访问的节点,然后当前节点的左子树指向 prev,假如 prev 不为空,prev 的右子树指向当前节点,再更新 pre。
最后递归右子树
注意:
注意 prev 要传引用,因为 prev 是要实时变化的
链表的头不要格外的去记录,因为是双向链表,一直 往左就找到了
七:从前序与中序遍历序列构造二叉树
题目描述:题目链接
代码:
思路:
利用前序找到根节点,再通过中序找到左右子树,从而构造出了一整颗树
注意:
递归结束的条件:left>right
注意 start 要传引用,因为要实时变化的。
八:后继者
题目:题目链接
代码:
思路:
中序找到第一个比 p 大的值就是后续
九:左子树之和
题目:(题目链接)
方法一:
代码:
方法二:
代码:
思路:
递归去找左树上和右树上的左叶子节点,相加即可
注意:
特别要注意的是 左叶子节点的判断条件:root->left!=nullptr && root->left->right==nullptr && root->left->left ==nullptr
十:找树左下角的值
题目:(题目链接)
方法一:
层序遍历,找到最下面一层,最先从队列里出来的树
方法二:
代码:
思路:
记录当前最左节点的高度,如果找到叶子节点的高度大于之前的,则该叶子节点为当前树的左下角
因为是前序遍历,所以同一层的,左子树优先,所以可以求出左下角
注意:
注意全局变量的使用
十一:路径总和
题目: (题目链接)
代码:
十二: 从前序与中序遍历序列构造二叉树
题目:(题目链接)
*代码:
总结:
二叉树的 oj 题考察的主要是递归思想的运用和 非递归时,对整个递归流程的理解。只有理解好递归的整个过程和思路,才能更好地学好二叉树
多写,多思考,多复习,多总结!!
持续更新中!!!
版权声明: 本文为 InfoQ 作者【雪芙花】的原创文章。
原文链接:【http://xie.infoq.cn/article/4f22231aa5394937d10f212d7】。未经作者许可,禁止转载。
评论