【一天一大 lee】填充每个节点的下一个右侧节点指针 II (难度:中等) - Day20200928

时间:2022-07-26
本文章向大家介绍【一天一大 lee】填充每个节点的下一个右侧节点指针 II (难度:中等) - Day20200928,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目:[1]

给定一个二叉树

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 所示。

提示:

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

抛砖引玉

层次遍历

思路

广度优先遍历(BFS)

遍历中集中处理每一层的数据,注意题目中要求:

  • next 指向下一个 right 节点
  • 优先存在左节点
  • 在处理时[a,b],a.next=b
/**
 * // 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 null
  let queue = [root]
  while (queue.length) {
    let len = queue.length,
      last = null
    for (let i = 1; i <= len; ++i) {
      let node = queue.shift()
      if (node.left) queue.push(node.left)
      if (node.right) queue.push(node.right)
      if (i !== 1) last.next = node
      last = node
    }
  }
  return root
}

使用已建立的 next 指针

从根节点开始逐个构建下一层的 next,构建后同层借助 next 构建,同层构建完成借助 right、left 开启下一层。

var connect = function(root) {
  if (root == null) return null
  let start = root, // 上一层构建next的触发点
    nextStart = null, // 下一轮构建next的触发点
    perv = null // 上一轮后构建的节点

  while (start) {
    // 开启新一层时 上一轮后构建的节点修改为null
    perv = null
    nextStart = null
    // 遍历的指针在同层节点中通过 next 连接(在遍历重来中构建了next,开启下次遍历时使用构建的next改变指针)
    for (let p = start; p; p = p.next) {
      // 先构建left,刷新perv 再构建right
      if (p.left) helper(p.left)
      if (p.right) helper(p.right)
    }
    // 更新触发点
    start = nextStart
  }

  function helper(p) {
    if (perv) perv.next = p
    if (nextStart == null) nextStart = p
    perv = p
  }
  return root
}