题目
题目链接:leetcode-cn.com/leetbook/re…
题解
层序遍历使用辅助队列就可以了,下面连接中有二叉树的层次遍历和其它遍历方式的 JavaScript 实现;
但是在此题中规定了输出的是每层节点为子数组构成的数组;所以确定当前节点所在的层数是重点;
1、借助一个队列和一个标识符
解题重点在于确定层数,所以这里在普通层次遍历的基础上添加一个标识符 # 来分隔各层;
/**
* 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) {
if(root === null) {
return [];
}
const len = root.length;
let temp = null;
let resultArr = [];
class Queue {
constructor() {
this.queue = [];
}
deQueue() {
return this.queue.shift();
}
enQueue(item) {
try {
this.queue.push(item);
return true;
}catch(err) {
return false;
}
}
isEmpty() {
const len = this.queue.length;
if(len <= 0) {
return true;
}else {
if(this.queue[len-1] === "#" && this.queue[0] === "#") {
return true;
} else {
return false;
}
}
}
}
const queue = new Queue();
queue.enQueue('#');
queue.enQueue(root);
while(!queue.isEmpty()) {
temp = queue.deQueue();
if(temp === "#") {
queue.enQueue("#");
let arr = [];
resultArr[resultArr.length] = arr;
temp = queue.deQueue()
}
resultArr[resultArr.length-1].push(temp.val);
if(temp.left != null) {
queue.enQueue(temp.left);
}
if(temp.right != null) {
queue.enQueue(temp.right);
}
}
return resultArr;
};
2、使用双队列
本题的重点在于确定节点的层数,所以也可以双队列来实现;
使用双队列的原理是根据入队的规律,如下:
- 根节点入队,然后取出根节点(这是第一层),将根节点左右孩子节点入队;
- 然后将队列中的所有节点取出(这是第二层),将所有取出的节点的左右孩子节点入队;
- 重复第 2 个步骤,直到队列为空时退出;
所以我们可以根据这个入队规律确定每个节点所处的层次;
将队列中的所有节点取出这个步骤应该怎么完成呢?使用另一个队列就好了;
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function(root) {
if(root === null) {
return [];
}
let temp = null;
let resultArr = [];
class Queue {
constructor() {
this.queue = [];
}
deQueue() {
return this.queue.shift();
}
enQueue(item) {
try {
this.queue.push(item);
return true;
}catch(err) {
return false;
}
}
isEmpty() {
const len = this.queue.length;
if(len <= 0) {
return true;
}else {
return false;
}
}
}
// 使用双队列
const mainQueue = new Queue()
secondQueue = new Queue();
mainQueue.enQueue(root);
while(!mainQueue.isEmpty()) {
let tempArr = []
while(!mainQueue.isEmpty()) {
secondQueue.enQueue(mainQueue.deQueue());
}
while(!secondQueue.isEmpty()) {
temp = secondQueue.deQueue();
tempArr.push(temp.val);
if(temp.left !== null) {
mainQueue.enQueue(temp.left)
}
if(temp.right !== null) {
mainQueue.enQueue(temp.right);
}
}
resultArr.push(tempArr);
}
return resultArr;
};
3、使用深度优先遍历(DFS)
前序遍历、中序遍历、后序遍历都可以,这里使用的是前序遍历;
因为我们的解题重点是要确定节点所在的层次,所以不使用层次遍历,使用其它遍历方法也是行的,只要能解决问题是不是~
这里通过改造普通的前序遍历的递归实现,即每次调用函数时不仅传入节点,也传入节点所在层数;
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function(root) {
const resultArr = [];
if(root === null) {
return [];
}
// 改造的前序遍历
function preOrder(root,level) {
if(root === null) {
return ;
}
if(!resultArr[level]) {
resultArr.push([]);
}
resultArr[level].push(root.val);
preOrder(root.left,level + 1);
preOrder(root.right,level + 1);
}
// 为了符合数组的下标从 0 开始,这里将根节点所在的层数认为是 0
preOrder(root,0);
return resultArr;
};
大家如果有更好的思路和解法,欢迎大家一起来讨论啊~
这是使用 JavaScript 对 LeetCode《初级算法》的每道题的总结和实现的其中一篇,汇总篇在这里: