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

题目描述

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

struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

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

示例:

提示:

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

要点分析

方法一: 利用上一层的next指针

每行设置一个行头指针, 再设置一个指针用于遍历行的每一个节点

  • 每个节点的左儿子节点的next为其右儿子节点,
  • 其右儿子节点的next为其next的左儿子节点

循环出口:

  • 行头指针的左儿子节点为空(层次遍历出口)
  • 行遍历指针为空(行内节点遍历出口)

易错点及注意事项:

  • 空树的单独判断
  • 循环跳出条件的判断
  • 注意区分行内遍历和行之间的层次遍历

AC代码如下:

/*
// Definition for a Node.
class Node {
public:int val;Node* left;Node* right;Node* next;Node() : val(0), left(NULL), right(NULL), next(NULL) {}Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}Node(int _val, Node* _left, Node* _right, Node* _next): val(_val), left(_left), right(_right), next(_next) {}
};
*/class Solution {public:Node* connect(Node* root) {if(root==nullptr) return nullptr;//判断是否为空链表Node* ptr=root;//设置行遍历指针Node* leftHead=root;//设置行头指针while(leftHead->left!=nullptr){ptr=leftHead;while(ptr!=nullptr){ptr->left->next=ptr->right;if(ptr->next!=nullptr){ptr->right->next=ptr->next->left;}ptr=ptr->next;}leftHead=leftHead->left;//注意此处不是ptr=ptr->left}return root;}
};

方法二: 广度优先搜索, 层次遍历完美二叉树

主要考察层次遍历的使用, 通过队列和BFS进行层次遍历

注意C++STL的正确使用以及next连接两个节点的正确位置

AC代码如下:

class Solution {public:Node* connect(Node* root) {if (root == nullptr) {return root;}// 初始化队列同时将第一层节点加入队列中,即根节点queue<Node*> Q;Q.push(root);// 外层的 while 循环迭代的是层数while (!Q.empty()) {// 记录当前队列大小int size = Q.size();// 遍历这一层的所有节点for(int i = 0; i < size; i++) {// 从队首取出元素Node* node = Q.front();Q.pop();// 连接if (i < size - 1) //注意每一行最后一个节点的next不赋值{node->next = Q.front();}// 拓展下一层节点if (node->left != nullptr) {Q.push(node->left);}if (node->right != nullptr) {Q.push(node->right);}}}// 返回根节点return root;}
};

方法三: 利用两个指针之间的关系

这种方法巧妙就在于其利用cur与pre之间的关系分类型, 分步将不同类型的节点初始化next

具体如下图:

public Node connect(Node root)
{if (root == null) return root;//cur我们可以把它看做是每一层的链表Node cur = root;while (cur != null) {//遍历当前层的时候,为了方便操作在下一层前面添加一个哑结点(注意这里是访问当前层的节点,然后把下一层的节点串起来)Node dummy = new Node(0);//pre表示下一层节点的前一个节点Node pre = dummy;//然后开始遍历当前层的链表//因为是完美二叉树,如果有左子节点就一定有右子节点while (cur != null && cur.left != null) {//让pre节点的next指向当前节点的左子节点,也就是把它串起来pre.next = cur.left;//然后再更新prepre = pre.next;//pre节点的next指向当前节点的右子节点,pre.next = cur.right;pre = pre.next;//继续访问这一行的下一个节点cur = cur.next;}//把下一层串联成一个链表之后,让他赋值给cur,//后续继续循环,直到cur为空为止cur = dummy.next;}return root;
}

力扣 填充每个节点的下一个右侧节点指针相关推荐

  1. 力扣116. 填充每个节点的下一个右侧节点指针(C++,附思路)

    题目链接在这里: 116. 填充每个节点的下一个右侧节点指针 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/popu ...

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

    116. 填充每个节点的下一个右侧节点指针 难度中等128 给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点.二叉树定义如下: struct Node {int val;Node ...

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

    2020-05-28 1.题目描述 填充每个节点的下一个右侧节点指针 2.题解 层次遍历即可 3.代码 /* // Definition for a Node. class Node { public ...

  4. [leetcode-117]填充每个节点的下一个右侧节点指针 II

    (1 AC) 填充每个节点的下一个右侧节点指针 I是完美二叉树.这个是任意二叉树 给定一个二叉树 struct Node {int val;Node *left;Node *right;Node *n ...

  5. 2.<tag-二叉树和层序遍历相关题>-lt.116. 填充每个节点的下一个右侧节点指针 + lt.117. 填充每个节点的下一个右侧节点指针 II 1

    lt.116. 填充每个节点的下一个右侧节点指针 [案例需求] [思路分析一, 迭代法] [代码实现] /* // Definition for a Node. class Node {public ...

  6. 二叉树:填充每个节点的下一个右侧节点指针(java)

    leetcode116:填充每个节点的下一个右侧节点指针 leetcode原题链接: 题目描述 递归解法一 递归方法二(效率更高) 二叉树专题 leetcode原题链接: 116题:填充每个节点的下一 ...

  7. LeetCode 116. 填充每个节点的下一个右侧节点指针

    https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/ 难度:中等   给定一个完美二叉树,其所有叶 ...

  8. 49. Leetcode 117. 填充每个节点的下一个右侧节点指针 II (二叉树-二叉树遍历)

    给定一个二叉树struct Node {int val;Node *left;Node *right;Node *next; } 填充它的每个 next 指针,让这个指针指向其下一个右侧节点.如果找不 ...

  9. 【数据结构与算法】之深入解析“填充每个节点的下一个右侧节点指针”的求解思路与算法示例

    一.题目要求 给定一个完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点. 二叉树定义如下: struct Node {int val;Node *left;Node *right;No ...

最新文章

  1. 内存存储器和外存储器的异同
  2. PgSQL · 应用案例 · 阿里云 RDS PostgreSQL 高并发特性 vs 社区版本
  3. C实现的一个简单的学生成绩管理系统
  4. 把地图中的道路以线条提取出来_入围 ICRA 2019 最佳论文:MIT利用粗粒度地图实现自动驾驶...
  5. 基于RadeonRays的光线追踪全局光照实现方案
  6. C# Memory Cache 踩坑记录
  7. html input触发器类型,几种触发器的Verliog语言描述
  8. java多线程02-----------------synchronized底层实现及JVM对synchronized的优化
  9. 【博士后招聘】浙江大学杨杰课题组-医学AI/大数据分析/自然语言处理
  10. 30+岁、没转管理、加不动班,我的竞争力从哪里来?
  11. Cannot add task ‘wrapper‘ as a task with that name already exists.
  12. iOS 蓝牙开发中数据收发的坑
  13. ERStudio逆向工程生成ER模型
  14. 计算机专业新生研讨课感悟,新生研讨课学习心得与收获
  15. 如何入门Python之Python基础教程详解
  16. 元气骑士机器人获取方法_元气骑士机器人怎么获得视频(机器人获取方法说明)...
  17. mongoDB 注册成开启自启动项
  18. 打造认可文化,是OKR成功的关键
  19. oracle 分组 最新,Oracle分组查询
  20. linux批量筛选序列变异位点,找变异流程之snp_call –WES学习之路

热门文章

  1. 《ANTLR 4权威指南 》一导读
  2. hdu4405 掷骰子走格子
  3. 9.2.2、Libgdx的输入处理之事件处理
  4. 手工释放linux内存——/proc/sys/vm/drop_caches
  5. 软件开发,维护与支持的困惑
  6. 存储过程出错会回滚吗_一个人做梦过程中不小心挂了,梦境会继续吗?
  7. C程序设计语言现代方法01:C语言概述
  8. c++ java setobjectarrayelement_java中jni的使用:C/C++操作java中的数组
  9. Redis-数据结构03-跳跃表(skiplist)
  10. python闹钟_用python做了个高级闹钟 欢迎借鉴