foreword
The blogger recently brushed up leetcode
and found that many problem-solving ideas are based on the sequence traversal of the binary tree when doing the binary tree set of questions, so I wrote this article and recorded the "artifact" of the binary tree sequence traversal application in actual combat.
[leetcode] 102. Level order traversal of binary tree
The layer-order traversal of a binary tree is somewhat different from the traditional pre-order, in-order, and post-order traversals. It traverses hierarchically, from left to right, and from top to bottom, so when I traverse the current layer nodes , it is definitely necessary to record the left
, of all nodes in the current layer right
, save them in the queue, and perform the next round of traversal until there are no nodes left
, , right
, which means that the last layer has been traversed.
Therefore, it is necessary to use an auxiliary data structure - 队列
, the queue is first-in, last-out, which conforms to the order of layer order traversal. In fact, this question is a combination question of 队列
+ .广度优先遍历
Just look at the code:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function(root) {
const res = [], queue = [];
queue.push(root);
if(root === null) return res;
while(queue.length !== 0) {
let level = [];
const length = queue.length
for(var i = 0; i < length; i++) {
var node = queue.shift();
level.push(node.val);
node.left && queue.push(node.left);
node.right && queue.push(node.right);
}
res.push(level);
}
return res;
};
Next we analyze the code line by line.
- First, a result and a queue are defined, corresponding to
res
andqueue
, the top-levelroot
nodes are added to the queue, and the loop is started. - In each
while
cycle, we take out the nodes (shift api
) sequentially from left to right and judge whether there are descendants ( ) in the next layer of each nodeleft、right
, and if so, add them to the queue. const length = queue.length
It records the initial state of the queue at the beginning of each layer traversal, ensuring that the content of the subsequentfor
cyclic traversal is the nodes of the current layer, andleft、right
the number of rounds of the current layer will not be affected by the nodes added to the queue.- Finally, all the nodes in the queue have been traversed, and
for
no new lower-level nodes are found in the loop, the loop ends, and the result is returned.
At this point, we have mastered the layer order traversal of the binary tree, so the following nine questions on the button only need to modify two or three lines of code in the template (no more), and it can be overthrown! You will really find that after understanding the sequence traversal, solving these related problems will be as simple as ducks in water
- 102. Level order traversal of binary tree
- 107. Level Traversal of Binary Tree II
- 199. Right View of Binary Tree
- 637. Layer Average of Binary Tree
- 429. Preorder traversal of N-ary tree
- 515. Find the Maximum Value in Each Tree Row
- 116. Fill the next right node pointer of each node
- 117. Fill each node's next right node pointer II
- 104. Maximum depth of binary tree
- 111. Minimum depth of binary tree
[leetcode] 107. Level order traversal of binary tree II
This question is very similar to , you only need to change the order of the 102.二叉树的层序遍历
final results, the code structure is exactly the same as 102.res
code:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrderBottom = function(root) {
var res = [], queue = [];
queue.push(root);
if(root === null) return res;
while(queue.length) {
let length = queue.length;
const level = [];
for(var i = 0; i < length; i++) {
var node = queue.shift();
level.push(node.val)
node.left && queue.push(node.left);
node.right && queue.push(node.right);
}
res.unshift(level);
}
return res;
};
[leetcode] 199. Right View of Binary Tree
As you can see from the description of this question, you need to collect the last node of each layer. With the "artifact", you already have an idea at this time, right? while
Doesn't it just need to add a judgment condition in each cycle for
and take out the last node? On the code!
code:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var rightSideView = function(root) {
var res = [], queue = [];
queue.push(root);
if(root === null ) return res;
while(queue.length !== 0 ){
const length = queue.length;
for(var i = 0; i < length; i++) {
var node = queue.shift();
if(i === length - 1) {
res.push(node.val);
}
node.left && queue.push(node.left);
node.right && queue.push(node.right);
}
}
return res;
};
[leetcode] 637. Level average of binary tree
This question only needs to calculate the average value of the nodes after each layer of nodes is collected. Compared with the previous questions, the difference is that the returned results of the collection are different, and there is no difference in the problem-solving code structure.
code:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var averageOfLevels = function(root) {
var res = [], queue = [];
queue.push(root);
if(root === null) return res;
while(queue.length !== 0) {
const length = queue.length;
let total = 0;
for(var i = 0; i < length; i++) {
let node = queue.shift();
total += node.val;
node.left && queue.push(node.left);
node.right && queue.push(node.right);
}
res.push(total / length);
}
return res;
};
[leetcode] 429. Level order traversal of N-ary tree
There will be a little bend in this question that needs to be detoured. First of all, the data structure is different. TreeNode
The nodes are like this:
/**
* // Definition for a Node.
* function Node(val,children) {
* this.val = val;
* this.children = children;
* };
*/
That is to say, in the loop of each layer of nodes, instead of collecting the nodes left
, right
we traverse the nodes children
and children
add the nodes in the queue.
code:
/**
* // Definition for a Node.
* function Node(val,children) {
* this.val = val;
* this.children = children;
* };
*/
/**
* @param {Node|null} root
* @return {number[][]}
*/
var levelOrder = function(root) {
var res = [], queue = [];
queue.push(root);
if(root === null) return res;
while(queue.length !== 0) {
var level = [];
var length = queue.length;
for(var i = 0; i < length; i++) {
var node = queue.shift();
level.push(node.val)
for(var item of node.children) {
item && queue.push(item);
}
}
res.push(level);
}
return res;
};
[leetcode] 515. Find the maximum value in each tree row
This question is similar 637.二叉树的层平均值
, except that the content collected by each layer becomes the maximum value.
code:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var largestValues = function(root) {
var res = [], queue = [];
queue.push(root);
if(root === null) return res;
while(queue.length !== 0) {
const length = queue.length;
const list = [];
for(var i = 0; i < length; i++) {
var node = queue.shift();
list.push(node.val);
node.left && queue.push(node.left);
node.right && queue.push(node.right);
}
res.push(Math.max(...list));
}
return res;
};
[leetcode] 116. Fill the next right node pointer of each node
This question does not need to reassemble the new return content, just need to reassemble root
each node in the reorganization, each TreeNode
default next
is null
, according to the requirements of the question, all nodes in each layer, we add to all nodes except the rightmost node Just one next
attribute, according to the first-in-first-out principle of the queue, next
the value is queue[0]
, which is the first item in the queue.
code:
/**
* // Definition for a Node.
* function Node(val, left, right, next) {
* this.val = val === undefined ? null : val;
* this.left = left === undefined ? null : left;
* this.right = right === undefined ? null : right;
* this.next = next === undefined ? null : next;
* };
*/
/**
* @param {Node} root
* @return {Node}
*/
var connect = function(root) {
var queue = [root];
if(root === null) return root;
while(queue.length) {
const length = queue.length;
for(var i = 0; i < length; i++) {
var node = queue.shift();
if(i < length - 1) {
node.next = queue[0];
}
node.left && queue.push(node.left);
node.right && queue.push(node.right);
}
}
return root;
};
[leetcode] 117. Fill the next right node pointer of each node II
This question is 116. 填充每个节点的下一个右侧节点指针
similar to , directly on the code.
code:
/**
* // Definition for a Node.
* function Node(val, left, right, next) {
* this.val = val === undefined ? null : val;
* this.left = left === undefined ? null : left;
* this.right = right === undefined ? null : right;
* this.next = next === undefined ? null : next;
* };
*/
/**
* @param {Node} root
* @return {Node}
*/
var connect = function(root) {
if (root === null) {
return null;
}
let queue = [root];
while (queue.length > 0) {
let n = queue.length;
for (let i=0; i<n; i++) {
let node = queue.shift();
if (i < n-1) node.next = queue[0];
if (node.left != null) queue.push(node.left);
if (node.right != null) queue.push(node.right);
}
}
return root;
};
[leetcode] 104. Maximum depth of binary tree
This problem is relatively simple, you only need to keep recording during the traversal process height
, and when the layer sequence traversal ends, return height
will be solved.
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var maxDepth = function(root) {
if(root === null) return root;
var queue = [root];
var height = 0;
while(queue.length > 0) {
const length = queue.length;
height++;
for(var i = 0; i < length; i++) {
var node = queue.shift();
node.left && queue.push(node.left);
node.right && queue.push(node.right);
}
}
return height
};
[leetcode] 111. Minimum depth of binary tree
This question is 104. 二叉树的最大深度
similar to this question, the difference is that the loop needs to be ended in advance. By judging whether the tree node is satisfied node.left === null && node.right === null
, you can know which node the minimum depth of the binary tree is, and just return it when traversing the node height
.
code:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var minDepth = function(root) {
if(root === null) return root;
var queue = [root];
var height = 0;
while(queue.length > 0) {
const n = queue.length;
height++;
for(var i = 0; i < n; i++) {
var node = queue.shift();
if(node.left === null && node.right === null ) {
return height;
}
node.left && queue.push(node.left);
node.right && queue.push(node.right);
}
}
return height;
};
end
The layer order traversal of the binary tree is essentially an "artifact" born out of the combination of 队列
+ , and you will find that it can solve many problems in the binary tree!广度优先遍历
leetcode
If this article is helpful to you, please like it~