⚓️作者简介:北京某能源高校非科班大四学生。
座右铭:“九层之台,起于垒土” 。所以学习技术须脚踏实地。
这里推荐一款刷题、模拟面试神器,可助你斩获大厂offer:点我免费刷题、模拟面试
牛客网是一个集笔面试系统、题库、课程教育、社群交流、招聘内推于一体的招聘类网站,更是一个专注于程序员的学习和成长的平台。
在某次浏览博客的过程中,我偶然点进一个链接,注册了牛客账号。一来到牛客首页,我就被其丰富的功能与良好的社区环境所吸引:
进入题库,更是有最新校招试题与专项练习:
在线编程更是有在线调试功能,可大大提高debug效率:
问答题下还有超多牛客用户交流:
总之,牛客是一个专注于程序员的学习和成长的平台,所以我极力推荐大家注册牛客,坚持刷题,充实自己,大厂offer便指日可待。
二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。上一节我们讲解了二叉树的前序、中序、后序的递归与非递归形式的遍历,这一节来刷几个进阶点的题目:
解题思路
什么是二叉树的层序遍历?简单来说就是一层一层的遍历二叉树,第一次遍历二叉树的根节点,第二次遍历二叉树的两个左右节点,以此类推。
一般来说二叉树的层序遍历要用到队列这种数据结构,每当一个节点出队就要将该节点的孩子入队,这样就可以保证遍历满足层序遍历的要求。当队列为空,这棵树也就遍历完成了。
但对于此题,我们需要返回一个二维向量,每个元素从前向后是二叉树的每一层遍历结果。所以当前一层的节点全部出队并保存入向量中后,这一层的遍历也就结束了,所以我们在遍历一层树前,需要获得前一层节点的数量,用来控制内层循环的次数。
算法流程:
C++解题代码:
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
/**
*
* @param root TreeNode类
* @return int整型vector>
*/
vector<vector<int> > levelOrder(TreeNode* root) {
// write code here
vector<vector<int>> vv;
if(!root) return vv;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
int n = q.size();
vector<int> v;
while(n){
TreeNode* node = q.front();
q.pop();
v.push_back(node->val);
--n;
if(node->left) q.push(node->left);
if(node->right) q.push(node->right);
}
vv.push_back(v);
}
return vv;
}
};
解题思路
本题也是层序遍历,不过是之字形的层序遍历,我们可以在上题的基础上进行改进:
算法流程:
C++解题代码:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
vector<vector<int> > Print(TreeNode* pRoot) {
vector<vector<int>> vv;
if(!pRoot) return vv;
stack<TreeNode*> s;
s.push(pRoot);
bool odd = true;
while(!s.empty()){
odd = !odd;
int n = s.size();
vector<int> v;
queue<TreeNode*> q;
while(n){
TreeNode* node = s.top();
s.pop();
v.push_back(node->val);
--n;
q.push(node);
}
n = q.size();
while(n){
TreeNode* node = q.front();
q.pop();
if(odd){
if(node->right) s.push(node->right);
if(node->left) s.push(node->left);
}else{
if(node->left) s.push(node->left);
if(node->right) s.push(node->right);
}
--n;
}
vv.push_back(v);
}
return vv;
}
};
示例:
解题思路:
由于二叉树的中序遍历得到的就是双向链表的序列,所以在中序遍历的基础上我们可以利用双指针改变节点的左右孩子指向,就可以解决本题。
算法步骤:
C++解题代码
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
TreeNode *head, *prenode;
TreeNode* Convert(TreeNode* pRootOfTree) {
convert(pRootOfTree);
prenode = nullptr;
return head;
}
private:
void convert(TreeNode* node){
if(!node) return;
convert(node->left);
if(!prenode) {
head = node;
}
else{
prenode->right = node;
node->left = prenode;
}
prenode = node;
convert(node->right);
}
};
我希望通过写博客来结束浑浑噩噩的生活,我更希望通过刷题结束人云亦云的思考。刷题不仅仅是刷题,还是我们与自己内心深处的对话。希望我们可以一起在牛客刷题交流,一起收割大厂offer!