今天的题目是搜索算法(广度优先搜索),用到了树这种数据结构,题目不是特别难,但都挺有意思的。
剑指 Offer 32 - I. 从上到下打印二叉树
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:
给定二叉树: [3,9,20,null,null,15,7]
,
3
/ \
9 20
/ \
15 7
返回:
[3,9,20,15,7]
提示:
节点总数 <= 1000
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> levelOrder(TreeNode* root) {
queue<TreeNode*> q;
vector<int> ans;
if(root == nullptr)return ans;
q.push(root);
while(q.empty() == false){
TreeNode *node = q.front();
q.pop();
ans.push_back(node->val);
if(node->left != nullptr)q.push(node->left);
if(node->right != nullptr)q.push(node->right);
}
return ans;
}
};
算法思路:
在学树的时候这种遍历叫层次遍历,学图的时候这叫广度优先搜索,广度优先的基本思路就是用一个队列存储每一个结点,然后执行先进先出的操作,每个弹出的结点再扩展其子节点到队列尾,这样就可以形成层次遍历(广度优先搜索)。
剑指 Offer 32 - II. 从上到下打印二叉树 II
从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
例如:
给定二叉树: [3,9,20,null,null,15,7]
,
3
/ \
9 20
/ \
15 7
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
提示:
节点总数 <= 1000
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> ans;
queue<TreeNode*> q;
if(root == nullptr)return ans;
q.push(root);
int i = 0;
while(q.empty() == false){
ans.push_back({});
for(int j = q.size(); j > 0; -- j){
TreeNode *node = q.front();
q.pop();
ans[i].push_back(node->val);
if(node->left != nullptr)q.push(node->left);
if(node->right != nullptr)q.push(node->right);
}
i ++;
}
return ans;
}
};
算法思路:
第二题思路和第一题思路大致相同,第二题只是在搜索时候记录该结点所在层数而已,这时只需要在弹出时做一点小改变,一批一批的弹出而不是一个个弹出,这里有个细节就是for(int j = q.size(); j > 0; -- j)
,这里不可以用for(int j = 0; j < q.size(); -- j)
,这是因为在批弹出的过程中也有新结点插入,q.size()
会改变,而我的目的本来只是弹出最原始的q.size()
个元素,所以后者不能用。
剑指 Offer 32 - III. 从上到下打印二叉树 III
请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
例如:
给定二叉树: [3,9,20,null,null,15,7]
,
3
/ \
9 20
/ \
15 7
返回其层次遍历结果:
[
[3],
[20,9],
[15,7]
]
提示:
节点总数 <= 1000
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> ans;
queue<TreeNode*> q;
if(root == nullptr)return ans;
q.push(root);
int i = 0;
bool tag = false;
while(q.empty() == false){
ans.push_back({});
stack<int> stac;
for(int j = q.size(); j > 0; -- j){
TreeNode *node = q.front();
q.pop();
if(tag){
stac.push(node->val);
}else{
ans[i].push_back(node->val);
}
if(node->left != nullptr)q.push(node->left);
if(node->right != nullptr)q.push(node->right);
}
while(stac.empty() == false){
ans[i].push_back(stac.top());
stac.pop();
}
tag = !tag;
i ++;
}
return ans;
}
};
算法思路:
第三题和第二题也大同小异,只是再偶数层插入结果时进行反转,这就达成了之字打印,至于如何反转可以用栈或者直接用vector
的reverse
,都可以实现。
【剑指Offer】系列:
【剑指Offer】栈
【剑指Offer】链表
【剑指Offer】字符串
【剑指Offer】查找算法
【剑指Offer】查找算法(1)