LeetCode 116,117 填充每个节点的下一个右侧节点指针(有些中等题,我也是能重拳出击的)

136 阅读3分钟

「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战

填充每个节点的下一个右侧节点指针

完美二叉树情况

给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

初始状态下,所有 next 指针都被设置为 NULL。

image.png

首先可以知道这是二叉树层序遍历的一道变形题,按照层序遍历的做法,我们将每一层的节点压入队列,依次处理每层节点,其次在层序遍历的做法下,我们得清楚这道变形的操作和限定条件,基于完美二叉树的特性,我们知道除了叶子节点外,每个节点都有其左右节点。我们把问题先限定到一两层中。

  1. 上一层操作下一层子节点的next指向
  2. 对于非叶子节点而言,它的左孩子节点的next指向它的右孩子节点,它的右孩子节点指向它的邻接节点(也就是同一层随它之后压入queue的节点)的左孩子 。前半部分好处理,但后半部分,我采用一个preNode记录这个未指向next指针的右孩子节点信息,因为此时邻接节点未弹出队列,获取不到邻接节点的左孩子信息 3.对于每一层的最后一个节点,我们直接将其next设置为null,并在下一层的开始,将preNode设置为null 代码如下:
var connect = function(root) {
    if (!root) return root;
    let queue = [];
    queue.push(root);
    while (queue.length) {
        // 记录当前层级节点数
        let length = queue.length;
        // 存放每一层节点
        let prenode = null;
        for (let i = 0; i < length; i++) {
            let node = queue.shift();
            if(prenode !== null) {prenode.next = node.left;}
            if (node.left !== null){
                queue.push(node.left);
                node.left.next = node.right;
            }
            if (node.right !== null) {
                queue.push(node.right);
                prenode = node.right
            } 
            if (i === length - 1) {node.next = null;}
        }
    }
    return root;
};

普通二叉树情况

给定一个二叉树

struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

初始状态下,所有 next 指针都被设置为 NULL。

image.png

普通二叉树的下一个右侧节点做法也很简单,直接当层处理当层节点next指向,使用preNode(记录)指向这一层上一个节点,设置上一个节点的next,到这一层的最后一个节点时,直接将next设置为null,preNode设置为null。

好家伙,刚做完题来写博客,写到现在发现,可以直接把普通二叉树的代码用在完美二叉树上,因为完美二叉树就是普通二叉树的一种,这个思路也更清晰明了,没这么多条件限定(嘻嘻嘻,安慰一下不是自己犯蠢,是题目顺序问题)

代码如下:

var connect = function(root) {
    if (!root) return root;
    let queue = [];
    queue.push(root);
    while (queue.length) {
        // 记录当前层级节点数
        let length = queue.length;
        // 存放每一层节点
        let preNode = null;
        for (let i = 0; i < length; i++) {
            let node = queue.shift();
            if (preNode) {
                preNode.next = node
            }
            node.left&&queue.push(node.left);
            node.right&&queue.push(node.right);
            preNode = node;
            if (i === length - 1) {
                node.next = null;
            }
        }
    }
    return root;
};