LeetCode《初级算法》树之二叉树的层序遍历 -- JavaScript

297 阅读2分钟

题目

题目链接:leetcode-cn.com/leetbook/re…

image.png


题解


层序遍历使用辅助队列就可以了,下面连接中有二叉树的层次遍历和其它遍历方式的 JavaScript 实现;

juejin.cn/post/702405…

但是在此题中规定了输出的是每层节点为子数组构成的数组;所以确定当前节点所在的层数是重点;


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、使用双队列

本题的重点在于确定节点的层数,所以也可以双队列来实现;

使用双队列的原理是根据入队的规律,如下:

  1. 根节点入队,然后取出根节点(这是第一层),将根节点左右孩子节点入队;
  2. 然后将队列中的所有节点取出(这是第二层),将所有取出的节点的左右孩子节点入队;
  3. 重复第 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《初级算法》的每道题的总结和实现的其中一篇,汇总篇在这里:

juejin.cn/post/700669…