二叉树常见 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】。未经作者许可,禁止转载。










 
    
评论