5

This topic aims to share some interesting or valuable topics found in the process of brushing Leecode. [Of course, the answer is based on js].
( should be regarded as the basic problem of binary tree, it is recommended to learn it, it is not difficult and classic )

topic related

  • Original title address: https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/
  • Topic description:

    The binary tree is printed in layers from top to bottom, the nodes of the same layer are printed in order from left to right, and each layer is printed to one line, for example, given a binary tree: [3,9,20,null,null,15,7]
       3
       / \
      9  20
        /  \
       15   7

    Return its hierarchical traversal result:

    [
      [3],
      [9,20],
      [15,7]
    ]

    Tips

    Considering that some students may seldom use js to brush leetcode, we will briefly introduce the data input tree type As in the above question, the input of the given binary tree , but should be as follows: Each node is a object

      const root = {
        val: 3,
        left: { // left表示当前节点的左侧子节点
          val: 9,
          left: null, // 对照上图可以看到 节点9没有左右子节点
          right: null,
        },
        right: {
          val: 20,
          left: {
            val: 15, // 对照上图可以看到 节点15没有左右子节点
            left: null, 
            right: null,
          }, 
          right: {
            val: 7, // 对照上图可以看到 节点7没有左右子节点
            left: null, 
            right: null,
          },
        }
      }

Analysis of ideas

This question is relatively basic. In fact, the test is BFS+ layer order traversal . How do you say it?
划重点.png

First of all, BFS (Breadth First Search) is breadth-first search , which means that during the traversal process, all adjacent nodes current node are always first traversed each time, and they are put into a queue, such as the example of the above question:

image.png

  • step1: First prepare an empty queue (that is, an array) [ ] , and put the root node into the array, that is, [3] ;
  • step2: First, takes out queue (the queue only has node 3 at this time, and the queue is empty after taking out), and then all its adjacent nodes (that is, the left and right child nodes in the binary tree) are added to the access queue in sequence , so the queue element is [9  20] at this time,
  • step3: Continue to follow the rules of the second step, take out node 9, and put the child node of 9 into the queue (no child nodes); then take node 20 out of , and store the child node of node 20 in the queue, At this time, the remaining elements of the queue are [15, 7] ;
  • step4: Continue to follow the rules of the second step, takes out , and puts the child node into the queue (no child nodes); then takes node 7 out of , and stores the child node of node 7 into the queue, at this time the queue The remaining elements are [] , and the queue is empty to end the whole process;

Carefully observe the above steps, have you found it?
image.png

  1. In addition to the first step initialization data, all subsequent steps were performed at repeated by step 2 of the rules ;
  2. Observe the removal results of each step:

    1. step2, take out[3];
    2. step3, take out [9, 20];
    3. step4, take out [15, 17];

    The result of each step here is exactly the result of each layer of 161f80082cc57c required by the question design.

  3. The end condition of the whole process is that the node queue is empty.
    At this point in this question, in fact, the general idea is already very clear, or, in fact, the above steps are already pseudo-code (no way, because the question itself is very typical -_-!)
  • First of all, the rule of step 2 must be the main function, because it loops all the time;
  • Secondly, the initial condition/end condition respectively correspond to the entering the queue , and the queue is empty;
  • only difficulty with 161f80082cc687 is how to handle [Layered Output] gracefully, and for this I suggest that you look directly at the complete code I posted at the end.
    image.png

full code

Then you can actually look at the code directly:

var levelOrder = function(root) {
    if (!root) { // 如果根节点都不存在 那直接结束 
        return [];
    }

    const nodes = [root]; // 初始化,对应前面分析里地初始条件,
    const res = []; 

    while(nodes.length > 0) { // 外层循环 当节点队列为空时结束
        const tempRes = [];
        let isEmpty = false;

        // 【注意点】这个内循环 也就是处理分层输出地精髓所在,大家可以仔细揣摩下这个循环条件
        // 尝试回答这里为什么不采用 “i=0 ;i<nodes.length; i++”的形式
        for(let i = nodes.length;i > 0 ; i--) { 
            const node = nodes.shift();
            tempRes.push(node.val);
            if(node.left) {
                nodes.push(node.left);
            }
            if(node.right) {
                nodes.push(node.right);
            }
        }
        res.push(tempRes);
       
    }
    return res;
 };

Well, the overall question is a basic question, so I won't draw a dynamic picture (it takes a lot of time to draw a picture), but I want to think about two questions for everyone to think about:

  1. That is the question in the code block, why is the condition of the inner loop not i=0 ;i<nodes.length; i++ ? If yes, what will happen?
  2. If this question evolves into the result of outputting depth-first traversal, how should the core points be changed?
    If you can answer the above two questions, then you basically understand this knowledge point!

image.png


安歌
7k 声望5.5k 粉丝

目前就职于Ringcentral厦门,随缘答题, 佛系写文章,欢迎私信探讨.