今日任务
144. 二叉树的前序遍历
- 题目链接: https://leetcode.cn/problems/binary-tree-preorder-traversal/description/
- 题目描述:
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
Code
递归
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> ans;
function<void(TreeNode *)> preOrder = [&] (TreeNode *node) -> void {
if(node == nullptr){
return;
}
ans.emplace_back(node->val);
preOrder(node->left);
preOrder(node->right);
};
preOrder(root);
return ans;
}
};
迭代 stack
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
// 迭代
vector<int> ans;
stack<TreeNode *> st;
if(root == nullptr){
return ans;
}
st.emplace(root);
while(!st.empty()){
TreeNode *cur = st.top();
ans.emplace_back(cur->val);
st.pop();
if(cur->right){
st.emplace(cur->right);
}
if(cur->left){
st.emplace(cur->left);
}
}
return ans;
}
};
145. 二叉树的后序遍历
- 题目链接: https://leetcode.cn/problems/binary-tree-postorder-traversal/description/
- 题目描述:
给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。
Code
递归
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> ans;
function<void(TreeNode *)> postOrder = [&] (TreeNode *node) -> void{
if(node == nullptr){
return;
}
postOrder(node->left);
postOrder(node->right);
ans.emplace_back(node->val);
};
postOrder(root);
return ans;
}
};
迭代
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
// 迭代
vector<int> ans;
stack<TreeNode *> st;
if(root == nullptr){
return ans;
}
st.emplace(root);
while(!st.empty()){
TreeNode *cur = st.top();
st.pop();
ans.emplace_back(cur->val);
if(cur->left){
st.emplace(cur->left);
}
if(cur->right){
st.emplace(cur->right);
}
}
reverse(ans.begin(), ans.end());
return ans;
}
};
94. 二叉树的中序遍历
- 题目链接: https://leetcode.cn/problems/binary-tree-inorder-traversal/description/
- 题目描述:
给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
Code
递归
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> ans;
function<void(TreeNode *)> inOrder = [&] (TreeNode *node) -> void{
if(node == nullptr){
return;
}
inOrder(node->left);
ans.emplace_back(node->val);
inOrder(node->right);
};
inOrder(root);
return ans;
}
};
迭代
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
//迭代
vector<int> ans;
stack<TreeNode *> st;
if(root == nullptr){
return ans;
}
TreeNode *cur = root;
while(cur || !st.empty()){
if(cur){
st.emplace(cur);
cur = cur->left;
}else{
cur = st.top();
st.pop();
ans.emplace_back(cur->val);
cur = cur->right;
}
}
return ans;
// 莫里斯遍历 将树变成链表
// 如中序遍历,将根节点放在左子树的最右节点下
}
};
标记
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
// White or Black
enum Color{
WHITE,
BLACK
};
vector<int> ans;
stack<pair<int, TreeNode *>> st;
st.emplace(make_pair(WHITE, root));
while(!st.empty()){
auto [color, cur] = st.top();
st.pop();
if(cur == nullptr){
continue;
}
if(color == WHITE){
st.emplace(WHITE, cur->right);
st.emplace(BLACK, cur);
st.emplace(WHITE, cur->left);
}else{
ans.emplace_back(cur->val);
}
}
return ans;
}
};
统一风格遍历(魔功大成)
标记法,将标记和节点一起入栈
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
// White or Black
enum Color{
WHITE,
BLACK
};
vector<int> ans;
stack<pair<int, TreeNode *>> st;
st.emplace(make_pair(WHITE, root));
while(!st.empty()){
auto [color, cur] = st.top();
st.pop();
if(cur == nullptr){
continue;
}
if(color == WHITE){
st.emplace(WHITE, cur->right);
st.emplace(BLACK, cur);
st.emplace(WHITE, cur->left);
}else{
ans.emplace_back(cur->val);
}
}
return ans;
}
};
添加nullptr,在应该输出的节点前加上空节点
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> ans;
stack<TreeNode *> st;
if(root){
st.emplace(root);
}
while(!st.empty()){
TreeNode *cur = st.top();
st.pop();
if(cur){
if(cur->right){
st.emplace(cur->right);
}
st.emplace(cur);
st.emplace(nullptr);
if(cur->left){
st.emplace(cur->left);
}
}else{
ans.emplace_back(st.top()->val);
st.pop();
}
}
return ans;
}
};
层序遍历
102. 二叉树的层序遍历
- 题目链接: https://leetcode.cn/problems/binary-tree-level-order-traversal/description/
- 题目描述:
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
Code 队列 Or 双数组
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
// if(root == nullptr){
// return {};
// }
// vector<vector<int>> ans;
// queue<TreeNode *> que;
// que.emplace(root);
// while(!que.empty()){
// int n = que.size();
// ans.emplace_back(vector<int>());
// for(int i = 0; i < n; i++){
// TreeNode *cur = que.front();
// que.pop();
// ans.back().emplace_back(cur->val);
// if(cur->left){
// que.emplace(cur->left);
// }
// if(cur->right){
// que.emplace(cur->right);
// }
// }
// }
// return ans;
// double array
if(root == nullptr){
return {};
}
vector<vector<int>> ans;
vector<TreeNode *> cur = {root}; // 直接赋值
while(!cur.empty()){
ans.emplace_back(vector<int>());
vector<TreeNode *> next;
for(auto & node : cur){
ans.back().emplace_back(node->val);
if(node->left){
next.emplace_back(node->left);
}
if(node->right){
next.emplace_back(node->right);
}
}
cur = move(next); // 移动赋值
}
return ans;
}
};
107. 二叉树的层序遍历 II
- 题目链接: https://leetcode.cn/problems/binary-tree-level-order-traversal-ii/description/
- 题目描述:
给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
Code 队列 Or 双数组
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
if(root == nullptr){
return {};
}
vector<vector<int>> ans;
// vector<TreeNode *> cur = {root};
// while(!cur.empty()){
// ans.emplace_back(vector<int>());
// vector<TreeNode *> next;
// for(auto node : cur){
// ans.back().emplace_back(node->val);
// if(node->left){
// next.emplace_back(node->left);
// }
// if(node->right){
// next.emplace_back(node->right);
// }
// }
// cur = move(next);
// }
queue<TreeNode *> que;
que.emplace(root);
while(!que.empty()){
int n = que.size();
ans.emplace_back(vector<int>());
for(int i = 0; i < n; i++){
TreeNode *cur = que.front();
que.pop();
ans.back().emplace_back(cur->val);
if(cur->left){
que.emplace(cur->left);
}
if(cur->right){
que.emplace(cur->right);
}
}
}
reverse(ans.begin(), ans.end());
return ans;
}
};
199. 二叉树的右视图
- 题目链接: https://leetcode.cn/problems/binary-tree-right-side-view/description/
- 题目描述:
给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
Code 队列 Or 双数组 Or 递归
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
// if(root == nullptr){
// return {};
// }
// vector<int> ans;
// queue<TreeNode *> que;
// que.emplace(root);
// while(!que.empty()){
// int n = que.size();
// while(n--){
// auto cur = que.front();
// que.pop();
// if(n == 0){
// ans.emplace_back(cur->val);
// }
// if(cur->left){
// que.emplace(cur->left);
// }
// if(cur->right){
// que.emplace(cur->right);
// }
// }
// }
// vector<TreeNode *> cur = {root};
// while(!cur.empty()){
// ans.emplace_back(cur.back()->val);
// vector<TreeNode *> next;
// for(auto node : cur){
// if(node->left){
// next.emplace_back(node->left);
// }
// if(node->right){
// next.emplace_back(node->right);
// }
// }
// cur = move(next);
// }
// return ans;
vector<int> ans;
function<void(TreeNode *, int)> dfs = [&] (TreeNode *node, int depth) -> void{
if(node == nullptr){
return;
}
if(depth == ans.size()){
ans.emplace_back(node->val);
}
dfs(node->right, depth + 1);
dfs(node->left, depth + 1);
};
dfs(root, 0);
return ans;
}
};
637. 二叉树的层平均值
- 题目链接:https://leetcode.cn/problems/average-of-levels-in-binary-tree/description/
- 题目描述:
给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。
Code 队列 Or 双数组
class Solution {
public:
vector<double> averageOfLevels(TreeNode* root) {
if(root == nullptr){
return {};
}
vector<double> ans;
// queue<TreeNode *> que;
// que.emplace(root);
// while(!que.empty()){
// int n = que.size();
// double tmp = 0;
// for(int i = 0; i < n; i++){
// auto cur = que.front();
// que.pop();
// tmp += cur->val;
// if(cur->left){
// que.emplace(cur->left);
// }
// if(cur->right){
// que.emplace(cur->right);
// }
// }
// ans.emplace_back(tmp / n);
// }
vector<TreeNode *> cur = {root};
while(!cur.empty()){
double sum = 0;
vector<TreeNode *> next;
for(auto node : cur){
sum += node->val;
if(node->left){
next.emplace_back(node->left);
}
if(node->right){
next.emplace_back(node->right);
}
}
ans.emplace_back(sum / cur.size());
cur = move(next);
}
return ans;
}
};
429. N 叉树的层序遍历
- 题目链接: https://leetcode.cn/problems/n-ary-tree-level-order-traversal/description/
- 题目描述:
给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。
树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。
Code 队列 or 双数组
class Solution {
public:
vector<vector<int>> levelOrder(Node* root) {
if(root == nullptr){
return {};
}
vector<vector<int>> ans;
// queue<Node *> que;
// que.emplace(root);
// while(!que.empty()){
// int n = que.size();
// ans.emplace_back(vector<int>());
// for(int i = 0; i < n; i++){
// auto cur = que.front();
// que.pop();
// ans.back().emplace_back(cur->val);
// for(auto node : cur->children){
// que.emplace(node);
// }
// }
// }
vector<Node *> cur = {root};
while(!cur.empty()){
ans.emplace_back(vector<int>());
vector<Node *> next;
for(auto &node : cur){
ans.back().emplace_back(node->val);
for (const auto& child : node->children) {
next.emplace_back(child);
}
}
cur = move(next);
}
return ans;
}
};
515. 在每个树行中找最大值
- 题目链接:https://leetcode.cn/problems/find-largest-value-in-each-tree-row/description/
- 题目描述:
给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。
Code 队列 or 双数组
class Solution {
public:
vector<int> largestValues(TreeNode* root) {
if(!root){
return {};
}
vector<int> ans;
// queue<TreeNode *> que;
// que.emplace(root);
// while(!que.empty()){
// int n = que.size();
// int target = INT_MIN;
// for(int i = 0; i < n; i++){
// auto cur = que.front();
// que.pop();
// target = max(target, cur->val);
// if(cur->left){
// que.emplace(cur->left);
// }
// if(cur->right){
// que.emplace(cur->right);
// }
// }
// ans.emplace_back(target);
// }
vector<TreeNode *> cur = {root};
while(!cur.empty()){
int target = INT_MIN;
vector<TreeNode *> next;
for(auto & node : cur){
target = max(target, node->val);
if(node->left){
next.emplace_back(node->left);
}
if(node->right){
next.emplace_back(node->right);
}
}
cur = move(next);
ans.emplace_back(target);
}
return ans;
}
};
116. 填充每个节点的下一个右侧节点指针 && 117 相同
- 题目链接: https://leetcode.cn/problems/populating-next-right-pointers-in-each-node/description/
- 题目描述:
Code BFS + 队列 / 数组 or DFS递归 or BFS + List
class Solution {
public:
Node* connect(Node* root) {
if(!root){
return nullptr;
}
// queue<Node *> que;
// que.emplace(root);
// while(!que.empty()){
// int n = que.size();
// vector<Node *> cur;
// for(int i = 0; i < n; i++){
// auto node = que.front();
// que.pop();
// cur.emplace_back(node);
// if(node->left){
// que.emplace(node->left);
// }
// if(node->right){
// que.emplace(node->right);
// }
// }
// for(int i = 0; i < n - 1; i++){
// cur[i]->next = cur[i + 1];
// }
// }
// vector<Node *> cur = {root};
// while(!cur.empty()){
// vector<Node *> next;
// for(int i = 0; i < cur.size() - 1; i++){
// auto node = cur[i];
// node->next = cur[i + 1];
// if(node->left){
// next.emplace_back(node->left);
// }
// if(node->right){
// next.emplace_back(node->right);
// }
// }
// if(cur.back()->left){
// next.emplace_back(cur.back()->left);
// }
// if(cur.back()->right){
// next.emplace_back(cur.back()->right);
// }
// cur = move(next);
// }
// DFS
// vector<Node *> pre;
// function<void(Node *, int)> dfs = [&] (Node *cur, int depth) ->void{
// if(cur == nullptr){
// return;
// }
// if(pre.size() == depth){
// pre.emplace_back(cur);
// }else{
// pre[depth]->next = cur;
// pre[depth] = cur;
// }
// dfs(cur->left, depth + 1);
// dfs(cur->right, depth + 1);
// };
// dfs(root, 0);
// BFS + LIST
auto dummy = make_unique<Node>();
auto cur = root;
while(cur){
dummy->next = nullptr;
Node *tmp = dummy.get();
while(cur){
if(cur->left){
tmp->next = cur->left;
tmp = cur->left;
}
if(cur->right){
tmp->next = cur->right;
tmp = cur->right;
}
cur = cur->next;
}
cur = dummy->next;
}
return root;
}
};