Populating Next Right Pointers in Each Node Total
Given a binary tree

struct TreeLinkNode {
      TreeLinkNode *left;
      TreeLinkNode *right;
      TreeLinkNode *next;
    }
Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL.

Initially, all next pointers are set to NULL.

Note:

You may only use constant extra space.
You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).
For example,
Given the following perfect binary tree,
         1
       /  \
      2    3
     / \  / \
    4  5  6  7
After calling your function, the tree should look like:
         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \  / \
    4->5->6->7 -> NULL

SOLUTION 1

我们可以用递归处理左右子树. 这个算法可能会消耗O(h)的栈空间。

 /* 试一下 recursion */
public void connect(TreeLinkNode root) {
if (root == null) {
return;
} rec(root);
} public void rec(TreeLinkNode root) {
if (root == null) {
return;
} if (root.left != null) {
root.left.next = root.right;
} if (root.right != null) {
root.right.next = root.next.left;
} rec(root.left);
rec(root.right);
}

2014.1229 redo:

 /*
3. A recursion version.
*/
public void connect3(TreeLinkNode root) {
if (root == null || root.left == null) {
return;
} root.left.next = root.right;
root.right.next = root.next == null ? null: root.next.left; connect(root.left);
connect(root.right);
}

SOLUTION 2

用层次遍历也可以相当容易解出来,而且这种方法用在下一题一点不用变。

但是 这个解法不能符合题意。题目要求我们使用 constant extra space.

 /*
* 使用level traversal来做。
* */
public void connect1(TreeLinkNode root) {
if (root == null) {
return;
} TreeLinkNode dummy = new TreeLinkNode(0);
Queue<TreeLinkNode> q = new LinkedList<TreeLinkNode>();
q.offer(root);
q.offer(dummy); while (!q.isEmpty()) {
TreeLinkNode cur = q.poll();
if (cur == dummy) {
if (!q.isEmpty()) {
q.offer(dummy);
}
continue;
} if (q.peek() == dummy) {
cur.next = null;
} else {
cur.next = q.peek();
} if (cur.left != null) {
q.offer(cur.left);
} if (cur.right != null) {
q.offer(cur.right);
}
}
}

 2014.1229 redo:

1.

 /*
1. Iterator.
*/
public void connect1(TreeLinkNode root) {
if (root == null) {
return;
} Queue<TreeLinkNode> q = new LinkedList<TreeLinkNode>();
q.offer(root); while (!q.isEmpty()) {
int size = q.size(); for (int i = 0; i < size; i++) {
TreeLinkNode cur = q.poll(); // ERROR 2: forget to determine if root don't have left and right.
if (cur.left == null) {
return;
} cur.left.next = cur.right;
cur.right.next = cur.next == null ? null : cur.next.left;
// bug 1: should put the offer inside the for loop
q.offer(cur.left);
q.offer(cur.right);
}
}
}

2.

 /*
2. Iterator. More simple version.
*/
public void connect2(TreeLinkNode root) {
if (root == null) {
return;
} Queue<TreeLinkNode> q = new LinkedList<TreeLinkNode>();
q.offer(root); while (!q.isEmpty()) {
int size = q.size(); for (int i = 0; i < size; i++) {
TreeLinkNode cur = q.poll(); // bug 1: should judge the size!
cur.next = (i == size - 1) ? null: q.peek(); if (cur.left != null) {
q.offer(cur.left);
q.offer(cur.right);
}
}
}
}

SOLUTION 3

把层次遍历修改一下,就是下面的解法了,我们使用2个循环,一个指针P1专门记录每一层的最左边节点,另一个指针P2扫描本层,把下一层的链接上。

下层链接完成后,将P1移动到它的左孩子即可。

这个算法的空间复杂度是O(1). 没有额外的空间。

 /*
The version that only has O(1) space complexity.
*/
public void connect(TreeLinkNode root) {
if (root == null) {
return;
} Iterator(root);
} public void Iterator(TreeLinkNode root) {
if (root == null) {
return;
} TreeLinkNode leftEnd = root; while(leftEnd != null) {
// go through the current level and link the next level.
TreeLinkNode cur = leftEnd;
while (cur != null) {
if (cur.left == null) {
break;
} cur.left.next = cur.right;
// 一定要记得判null.
cur.right.next = cur.next == null ? null: cur.next.left; cur = cur.next;
} // get to the next level.
leftEnd = leftEnd.left;
}
}

 2014.1229 redo:

 /*
4. Another constant iterator version.
*/
public void connect(TreeLinkNode root) {
if (root == null) {
return;
} TreeLinkNode leftEnd = root;
while (leftEnd != null && leftEnd.left != null) {
TreeLinkNode cur = leftEnd;
while (cur != null) {
cur.left.next = cur.right;
cur.right.next = cur.next == null ? null: cur.next.left; cur = cur.next;
} leftEnd = leftEnd.left;
}
}

GITHUB:

https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/tree/Connect_2014_1229.java

LeetCode: Populating Next Right Pointers in Each Node 解题报告的更多相关文章

  1. 【LeetCode】116. 填充每个节点的下一个右侧节点指针 Populating Next Right Pointers in Each Node 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcode ...

  2. LeetCode:Populating Next Right Pointers in Each Node I II

    LeetCode:Populating Next Right Pointers in Each Node Given a binary tree struct TreeLinkNode { TreeL ...

  3. [LeetCode] Populating Next Right Pointers in Each Node II 每个节点的右向指针之二

    Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...

  4. [LeetCode] Populating Next Right Pointers in Each Node 每个节点的右向指针

    Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *nex ...

  5. LeetCode——Populating Next Right Pointers in Each Node II

    Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...

  6. [leetcode]Populating Next Right Pointers in Each Node II @ Python

    原题地址:https://oj.leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/ 题意: Follow up ...

  7. LeetCode: Populating Next Right Pointers in Each Node II 解题报告

    Populating Next Right Pointers in Each Node IIFollow up for problem "Populating Next Right Poin ...

  8. LEETCODE —— Populating Next Right Pointers in Each Node

    Populating Next Right Pointers in Each Node Given a binary tree struct TreeLinkNode { TreeLinkNode * ...

  9. LeetCode - Populating Next Right Pointers in Each Node II

    题目: Follow up for problem "Populating Next Right Pointers in Each Node". What if the given ...

随机推荐

  1. (转)Content-Disposition的使用和注意事项

    最近不少Web技术圈内的朋友在讨论协议方面的事情,有的说web开发者应该熟悉web相关的协议,有的则说不用很了解.个人认为这要分层次来看待这个问 题,对于一个新手或者刚入门的web开发人员而言,研究协 ...

  2. 虚拟机和宿主机不能互ping的解决办法等

    1. 虚拟机和宿主机不能互ping的解决办法:禁用无关虚拟网卡. 2. 有时有效光驱设备为cdrom1. 3. CentOS 6.3 图形界面切换用户:System->Log Out

  3. mybatis对mysql进行分页

    Mybatis对mysql数据库分页 在generator中增加插件,下载地址http://download.csdn.net/detail/shunlongjin/6937045 <plugi ...

  4. web.config配置数据库连接(转)

    摘自:http://www.cnblogs.com/breezeblew/archive/2008/05/01/1178719.html 第一种: 取连接字符串 string connString = ...

  5. HUDOJ-----1394Minimum Inversion Number

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  6. 使用Apache FtpServer

    Java大法一统天下.遇到任何问题,先查一下Java中的解决方案. 地球上的许多事情,在Java中都能找到完美的解决方案. FtpServer是apache MINA项目的一个子项目,它实现了一个ft ...

  7. 【LeetCode】42. Trapping Rain Water

    Trapping Rain Water Given n non-negative integers representing an elevation map where the width of e ...

  8. 如何判断Android手机当前是否联网?

    如果拟开发一个网络应用的程序,首先考虑是否接入网络,在Android手机中判断是否联网可以通过 ConnectivityManager 类的isAvailable()方法判断, 首先获取网络通讯类的实 ...

  9. ucosii事件控制块------消息邮箱与消息队列

    UCOSII 使用叫做事件控制块(ECB)的数据结构来描述诸如信号量.邮箱(消息邮箱)和消息队列这些事件 #define OS_EVENT_EN (((OS_Q_EN > 0u) &&a ...

  10. python标准库介绍——14 gc 模块详解

    ==gc 模块== (可选, 2.0 及以后版本) ``gc`` 模块提供了到内建循环垃圾收集器的接口. Python 使用引用记数来跟踪什么时候销毁一个对象; 一个对象的最后一个引用一旦消失, 这个 ...