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

2023-05-13,,

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

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

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

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

 

示例:

输入:{"$id":"1","left":{"$id":"2","left":{"$id":"3","left":null,"next":null,"right":null,"val":4},"next":null,"right":{"$id":"4","left":null,"next":null,"right":null,"val":5},"val":2},"next":null,"right":{"$id":"5","left":{"$id":"6","left":null,"next":null,"right":null,"val":6},"next":null,"right":{"$id":"7","left":null,"next":null,"right":null,"val":7},"val":3},"val":1}

输出:{"$id":"1","left":{"$id":"2","left":{"$id":"3","left":null,"next":{"$id":"4","left":null,"next":{"$id":"5","left":null,"next":{"$id":"6","left":null,"next":null,"right":null,"val":7},"right":null,"val":6},"right":null,"val":5},"right":null,"val":4},"next":{"$id":"7","left":{"$ref":"5"},"next":null,"right":{"$ref":"6"},"val":3},"right":{"$ref":"4"},"val":2},"next":null,"right":{"$ref":"7"},"val":1}

解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。

 

提示:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解答:

解法1:递归

对于这个完美二叉树,其实对于每个节点,一共有两步,如图:

那么递归的过程就是这么两步,第一步是处理左子树的next,第二步处理右子树的next,那么这个根节点也就完成任务了,就可以往下递归了

也就是往左右子树递归。

 1 /*
2 // Definition for a Node.
3 class Node {
4 public int val;
5 public Node left;
6 public Node right;
7 public Node next;
8
9 public Node() {}
10
11 public Node(int _val,Node _left,Node _right,Node _next) {
12 val = _val;
13 left = _left;
14 right = _right;
15 next = _next;
16 }
17 };
18 */
19 class Solution {
20 public Node connect(Node root) {
21 if(root==null||root.left==null)
22 return root;
23
24 root.left.next=root.right;
25
26 if(root.next!=null)
27 root.right.next=root.next.left;
28
29 connect(root.left);
30 connect(root.right);
31 return root;
32 }
33 }

解法2:迭代

也就是不用list的层序遍历,怎么样才能不用list的额外空间呢?就是用这题目的next指针来引出下一个需要遍历的节点。

这里跟上面的区别就在于一个节点处理完了以后去处理左右子树的递归结构,然而这里不是这样,这里是处理完这一层的结构,再去处理下一层的结构,就这样一层层的遍历到最后一层结束。

 1 /*
2 // Definition for a Node.
3 class Node {
4 public int val;
5 public Node left;
6 public Node right;
7 public Node next;
8
9 public Node() {}
10
11 public Node(int _val,Node _left,Node _right,Node _next) {
12 val = _val;
13 left = _left;
14 right = _right;
15 next = _next;
16 }
17 };
18 */
19 class Solution {
20 public Node connect(Node root) {
21 if(root==null)
22 return null;
23 Node level=root;
24 Node worker=root;
25 while(level.left!=null)
26 {
27 worker.left.next=worker.right;
28 if(worker.next==null)
29 {
30 level=level.left;
31 worker=level;
32 }
33 else
34 {
35 worker.right.next=worker.next.left;
36 worker=worker.next;
37 }
38 }
39 return root;
40 }
41 }

解法3:递归的分割法

这里第三种看上去比较爽的,因为是完美二叉树,所以将树的结构分割成两半,将分割成两半的连起来的部分连起来,然后再往左右子树分割,是比较精彩的递归。

 1 /*
2 // Definition for a Node.
3 class Node {
4 public int val;
5 public Node left;
6 public Node right;
7 public Node next;
8
9 public Node() {}
10
11 public Node(int _val,Node _left,Node _right,Node _next) {
12 val = _val;
13 left = _left;
14 right = _right;
15 next = _next;
16 }
17 };
18 */
19 class Solution {
20 public Node connect(Node root) {
21 if(root==null)
22 return root;
23 Node left=root.left;
24 Node right=root.right;
25 while(left!=null)
26 {
27 left.next=right;
28 left=left.right;
29 right=right.left;
30 }
31 Node l=connect(root.left);
32 Node r=connect(root.right);
33 return root;
34 }
35 }

leetcode116. 填充每个节点的下一个右侧指针的相关教程结束。

《leetcode116. 填充每个节点的下一个右侧指针.doc》

下载本文的Word格式文档,以方便收藏与打印。