「前端刷题」117. 填充每个节点的下一个右侧节点指针 II

256 阅读2分钟

「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」。

题目

链接:leetcode-cn.com/problems/po…

给定一个二叉树

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

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

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

进阶:

  • 你只能使用常量级额外空间。
  • 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。

示例:

输入:root = [1,2,3,4,5,null,7] 输出:[1,#,2,3,#,4,5,7,#] **解释:**给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化输出按层序遍历顺序(由 next 指针连接),'#' 表示每层的末尾。

提示:

  • 树中的节点数小于 6000
  • -100 <= node.val <= 100

思路

很少做树的题目,这题解的也不是很优秀。(好几天前的每日一题了,在写题解的时候断网没保存,现在又写一遍)
运用到的是层次遍历的思想,将父节点中的子节点一一压入栈中,然后遍历修改将其next指针。
修改完后将子节点压入父节点栈中。
如此循环,最后得出答案。

代码

/**
 * // 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 root
    let parent = [root]; // 父节点栈
    while(parent.length > 0){
        let tmp = []; // 子节点栈
        while(parent.length > 0){ // 换取当前层全部子节点
            let node = parent.shift();
            if(node.left) tmp.push(node.left)
            if(node.right) tmp.push(node.right) 
        }
        for(let i=0;i<tmp.length;i++){ // 修改next指向及压入父节点栈
            if(tmp[i+1] != null) tmp[i].next = tmp[i+1]
            parent.push(tmp[i])
        }
    }
    return root
};

思路2

  • 队列r,放入root
  • 循环1队列长度 > 0 继续
  • 循环2l > 0继续,l - 1
    • 从队列中拿出第一个元素,取出左右节点,放入队列尾部
    • l > 0继续,l - 1,重复上一步
    • l = 0,循环2结束,回到循环1
  • 循环1,更新l = 新队列长度 = 循环2中放入元素的个数
    • l > 0继续 循环2
    • l = 0终止循环
  • 循环12,实现 二叉树 的 广度优先搜索
    • 同一层的全部节点 都被放入队列后,才进入 下一层
    • push:同层节点放入顺序 = 从左到右
    • shift:同层节点拿出顺序 = 从左往右
      • 拿出一个节点n
        • l > 0:同层还有节点,右节点 next = r[0]
        • l = 0:同层没有节点,右节点 next = null

代码

/**
 * // 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 r = root && [root] || [], l
    while(l = r.length) {
        while(l-- > 0) {
            var n = r.shift()
            n.next = l ? r[0] : null
            n.left && r.push(n.left)
            n.right && r.push(n.right)
        }
    }
    return root
};