题解一:递归(前序遍历)
主要思路:前序遍历,中、左、右
左边的节点一定先于右边节点遍历到,加入至对应的数组中,满足层序遍历的要求;
要点:
1、利用一个level变量标记当前递归的深度,将节点的值push到当前深度的数组的后面;
2、level变量大于res数组的size,说明第一次进入二叉树本层,对res扩容;
扩展:
前序:中、左、右
中序:左、中、右
后续:左、右、中
三种遍历都是左边节点一定比右边节点先遍历到,那么push_back至对应深度的数组次序也一定与层次遍历一致;所以针对此方法,中序、后序一样可以实现层次遍历。
对示例1模拟前序遍历,如下图所示:
复杂度分析:
时间复杂度:O(n),n为二叉树的节点数;
空间复杂度:O(n),除去存储节点值的空间,最差情况:二叉树退化成链表,递归深度为N;
实现如下:
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
/**
*
* @param root TreeNode类
* @return int整型vector<vector<>>
*/
//前序遍历模板;
void f(TreeNode* root,int level,vector<vector<int>> &res){
if(!root)return ;
if(level>=res.size()){//最新的深度,申请一个数组存储;
res.push_back(vector<int> {});
}
res[level].push_back(root->val);
f(root->left,level+1,res);//遍历左子树;
f(root->right,level+1,res);//遍历右子树;
}
vector<vector<int> > levelOrder(TreeNode* root) {
// write code here
vector<vector<int>> res;//存储最终结果;
f(root,0,res);//前序遍历;
return res;//返回结果;
}
};题解二:BFS(迭代)
主要思路:广度优先
如下图所示:一层一层的遍历二叉树,
1、遍历到一个节点,将左右个孩子加入队列;
2、一次遍历二叉树的一层;
3、怎么确定能遍历一层:每次遍历队列,先记录队列的大小size,出队size次,这些值即为一层,存入res数组,并通过1、2将下一层的节点存入队列;
对示例1模拟前序遍历,如下图所示:
复杂度分析:
时间复杂度:O(n),每个点进队出队各一次,遍历了整个二叉树。
空间复杂度:O(n),队列中元素的个数不超过 n 个,所以空间复杂度为 O(n)。
实现如下:
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
/**
*
* @param root TreeNode类
* @return int整型vector<vector<>>
*/
vector<vector<int> > levelOrder(TreeNode* root) {
// write code here
vector<vector<int> > vv;
if(!root){
return vv;//二叉树为空
}
queue<TreeNode*> qq;//队列存放相邻两层节点;
qq.push(root);
while(!qq.empty()){
vector<int> tempv;
int size=qq.size();
for(int i=0;i<size;++i){//将一层的节点size出队;
TreeNode* tt=qq.front();
qq.pop();
tempv.push_back(tt->val);
//将下一层的节点入队;
if(tt->left)qq.push(tt->left);
if(tt->right)qq.push(tt->right);
}
vv.push_back(tempv);//加入将要返回的数组中;
}
return vv;//返回最终结果
}
};二叉树遍历相关题目集:
二叉树中是否存在节点和为指定值的路径
二叉树的最大深度
二叉树中序遍历

京公网安备 11010502036488号