102. Binary Tree Level Order Traversal
题目:
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).
For example:
Given binary tree [3,9,20,null,null,15,7]
,
3
/ \
9 20
/ \
15 7
return its level order traversal as:
[
[3],
[9,20],
[15,7]
]
这道题的本质就是层次遍历二叉树,并按层打印出所有节点。感觉和之前的maximum depth的BFS做法是一样的,使用queue来存储节点。由于要求按层打印,于是在对每一层遍历的过程中,设立一个临时的vector对该层节点进行存储即可,还是比较简单的。代码如下,时间100%,空间43.96%:
/*
* @lc app=leetcode id=102 lang=cpp
*
* [102] Binary Tree Level Order Traversal
*/
/**
* 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>> result;
if (!root) {
return result;
}
queue<TreeNode*> nodes;
nodes.push(root);
while (!nodes.empty()) {
int size = nodes.size();
vector<int> temp;
for (int i = 0; i < size; i++) {
TreeNode* front = nodes.front();
nodes.pop();
temp.push_back(front->val);
if (front->left) {
nodes.push(front->left);
}
if (front->right) {
nodes.push(front->right);
}
}
result.push_back(temp);
}
return result;
}
};
2020.09.27 Java:
Runtime: 1 ms, faster than 62.18% of Java online submissions for Binary Tree Level Order Traversal.
Memory Usage: 39.2 MB, less than 98.57% of Java online submissions for Binary Tree Level Order Traversal.
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
if (root == null) {
return new ArrayList<>();
}
Queue<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
List<List<Integer>> result = new ArrayList<>();
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> level = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
level.add(node.val);
}
result.add(level);
}
return result;
}
}
除了常规的层次遍历BFS以外,还有一种DFS的骚操作,看discussion里说是类似于前序遍历,采用递归实现。在递归函数的参数中,还需要传递当前所在的层的层数,用于判断递归的次数和把节点的值塞到对应的层数中。在递归函数中,递归基是当根节点为空时;在其他条件下,需要通过层数和结果vector的数值来判断是否为第一次遍历,也就是刚开始的向下遍历,可以算是用于计算层数的部分吧,有多少层就要push多少个层的vector进去,并且把当前节点的值塞到对应的层数中,然后往左边遍历,最后往右边遍历,确实也就是前序遍历的顺序了。代码如下,时间93.09%,空间8.51%:
/*
* @lc app=leetcode id=102 lang=cpp
*
* [102] Binary Tree Level Order Traversal
*/
/**
* 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>> result;
void dfs(TreeNode* root, int depth) {
if (!root) {
return;
}
if (depth == result.size()) {
result.push_back(vector<int>());
}
result[depth].push_back(root->val);
dfs(root->left, depth + 1);
dfs(root->right, depth + 1);
}
vector<vector<int>> levelOrder(TreeNode* root) {
dfs(root, 0);
return result;
}
};
2020.09.27 Java:
DFS的思想在于通过把层数作为一个参数,并通过检查result的大小来判断是否之前已经遍历过这个层的节点,如果没遍历过(即层数=result.size())则建一个新层,如果遍历过就取出对应的list并把当前节点加进去。
Runtime: 0 ms, faster than 100.00% of Java online submissions for Binary Tree Level Order Traversal.
Memory Usage: 39.3 MB, less than 95.93% of Java online submissions for Binary Tree Level Order Traversal.
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
dfs(root, 0, result);
return result;
}
private void dfs(TreeNode root, int level, List<List<Integer>> result) {
if (root == null) {
return;
}
if (level == result.size()) {
result.add(new ArrayList<>());
}
List<Integer> levelList = result.get(level);
levelList.add(root.val);
dfs(root.left, level + 1, result);
dfs(root.right, level + 1, result);
}
}
107. Binary Tree Level Order Traversal II
题目:
Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).
For example:
Given binary tree [3,9,20,null,null,15,7]
,
3
/ \
9 20
/ \
15 7
return its bottom-up level order traversal as:
[
[15,7],
[9,20],
[3]
]
这道题的本质就是把前面一道题的输出给倒过来。看了一圈discussion好像没什么其他的insight,于是就重新复习了前面一道题的层次遍历两种方法,最后把vector给reverse一下。除了巩固毫无收获的一道题,就和之前的放在一起了。下面贴代码:
BFS:
/*
* @lc app=leetcode id=107 lang=cpp
*
* [107] Binary Tree Level Order Traversal II
*/
/**
* 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>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> result;
if (!root) {
return result;
}
queue<TreeNode*> nodes;
nodes.push(root);
while (!nodes.empty()) {
int size = nodes.size();
vector<int> temp;
for (int i = 0; i < size; i++) {
TreeNode* front = nodes.front();
nodes.pop();
temp.push_back(front->val);
if (front->left) {
nodes.push(front->left);
}
if (front->right) {
nodes.push(front->right);
}
}
result.push_back(temp);
}
reverse(result.begin(), result.end());
return result;
}
};
DFS:
/*
* @lc app=leetcode id=107 lang=cpp
*
* [107] Binary Tree Level Order Traversal II
*/
/**
* 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>> result;
void dfs(TreeNode* root, int depth) {
if (!root) {
return;
}
if (depth == result.size()) {
result.push_back(vector<int>());
}
result[depth].push_back(root->val);
dfs(root->left, depth + 1);
dfs(root->right, depth + 1);
}
vector<vector<int>> levelOrderBottom(TreeNode* root) {
dfs(root, 0);
reverse(result.begin(), result.end());
return result;
}
};