Populating Next Right Pointers in Each Node II
Follow up for problem "Populating Next Right Pointers in Each Node".

What if the given tree could be any binary tree? Would your previous solution still work?

Note:

You may only use constant extra space.
For example,
Given the following binary tree,
         1
       /  \
      2    3
     / \    \
    4   5    7
After calling your function, the tree should look like:
         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \    \
    4-> 5 -> 7 -> NULL

SOLUTION 1

本题还是可以用Level Traversal 轻松解出,连代码都可以跟上一个题目一模一样。Populating Next Right Pointers in Each Node Total

但是不符合空间复杂度的要求:constant extra space.

时间复杂度: O(N)

 /**
* Definition for binary tree with next pointer.
* public class TreeLinkNode {
* int val;
* TreeLinkNode left, right, next;
* TreeLinkNode(int x) { val = x; }
* }
*/
public class Solution {
public void connect(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);
}
} }
}

SOLUTION 2

我们可以用递归解出。注意从右往左加next。否则的话 右边未建立,左边你没找不到next. Space Complexity:

时间复杂度: O(N)

 public void connect(TreeLinkNode root) {
if (root == null) {
return;
} TreeLinkNode cur = root.next;
TreeLinkNode next = null;
// this is very important. should exit after found the next.
while (cur != null && next == null) {
if (cur.left != null) {
next = cur.left;
} else if (cur.right != null) {
next = cur.right;
} else {
cur = cur.next;
}
} if (root.right != null) {
root.right.next = next;
next = root.right;
} if (root.left != null) {
root.left.next = next;
} // The order is very important. We should deal with right first!
connect(root.right);
connect(root.left);
}

2014.1229 redo:

但现在leetcode加强数据了,不管怎么优化,递归的版本再也不能通过,都TLE

 // SOLUTION 2: REC
public void connect(TreeLinkNode root) {
if (root == null) {
return;
} TreeLinkNode dummy = new TreeLinkNode(0);
TreeLinkNode pre = dummy; if (root.left != null) {
pre.next = root.left;
pre = root.left;
} if (root.right != null) {
pre.right = root.right;
pre = root.right;
} if (root.left == null && root.right == null) {
return;
} // Try to find the next node;
TreeLinkNode cur = root.next;
TreeLinkNode next = null;
while (cur != null) {
if (cur.left != null) {
next = cur.left;
break;
} else if (cur.right != null) {
next = cur.right;
break;
} else {
cur = cur.next;
}
} pre.next = next; if (root.right != null && (root.right.left != null || root.right.right != null)) {
connect(root.right);
} if (root.left != null && (root.left.left != null || root.left.right != null)) {
connect(root.left);
} }

SOLUTION 3

我们可以用Iterator 直接解出。并且不开辟额外的空间,也就是说空间复杂度是 O(1)

时间复杂度: O(N)

感谢 http://www.geeksforgeeks.org/connect-nodes-at-same-level-with-o1-extra-space/ 的作者

 /*
Solution 3: iterator with O(1) space.
*/
public void connect(TreeLinkNode root) {
if (root == null) {
return;
} connIterator(root);
} /*
This is a iterator version.
*/
public void connIterator(TreeLinkNode root) {
TreeLinkNode leftEnd = root;
while (leftEnd != null) {
TreeLinkNode p = leftEnd; // Connect all the nodes in the next level together.
while (p != null) { // find the
TreeLinkNode next = findLeftEnd(p.next); if (p.right != null) {
p.right.next = next;
next = p.right;
} if (p.left != null) {
p.left.next = next;
} // continue to deal with the next point.
p = p.next;
} // Find the left end of the NEXT LEVEL.
leftEnd = findLeftEnd(leftEnd);
} } // Find out the left end of the next level of Root TreeNode.
public TreeLinkNode findLeftEnd(TreeLinkNode root) {
while (root != null) {
if (root.left != null) {
return root.left;
} if (root.right != null) {
return root.right;
} root = root.next;
} return null;
}

SOLUTION 4 (2014.1229):

在sol3基础上改进,引入dummynode,我们就不需要先找到最左边的点了。空间复杂度是 O(1)时间复杂度: O(N)

 // SOLUTION 1: Iteration
public void connect1(TreeLinkNode root) {
if (root == null) {
return;
} TreeLinkNode leftEnd = root; // Bug 1: don't need " && leftEnd.left != null"
while (leftEnd != null) {
TreeLinkNode cur = leftEnd; TreeLinkNode dummy = new TreeLinkNode(0);
TreeLinkNode pre = dummy;
while (cur != null) {
if (cur.left != null) {
pre.next = cur.left;
pre = cur.left;
} if (cur.right != null) {
pre.next = cur.right;
pre = cur.right;
} cur = cur.next;
}
leftEnd = dummy.next;
}
}

CODE ON GITHUB:

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

Connect2.java

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

  1. 【LeetCode】117. Populating Next Right Pointers in Each Node II 解题报告(Python)

    [LeetCode]117. Populating Next Right Pointers in Each Node II 解题报告(Python) 标签: LeetCode 题目地址:https:/ ...

  2. [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 ...

  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 II @ Python

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

  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 ...

  6. [LeetCode] [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 ...

  7. 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 ...

  8. Leetcode 笔记 117 - Populating Next Right Pointers in Each Node II

    题目链接:Populating Next Right Pointers in Each Node II | LeetCode OJ Follow up for problem "Popula ...

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

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

随机推荐

  1. OpenERP7.0安装后提示“not supported" ,如何去掉此提示

    转自:http://blog.csdn.net/vnsoft/article/details/17581831 下载了新版本的OpenERP7.0安装测试,发现在登录后会提示如图的内容. 经过测试发现 ...

  2. uploadify上传之前判断一个input输入框是否为空

    onUploadStart:function(file){ if ($("#ContractCode").val() == "") { alert(" ...

  3. eclipse 配置多个tomcat

      eclipse 配置多个tomcat CreateTime--2018年4月23日15:32:28 Author:Marydon windows-->Preferences-->Ser ...

  4. SET GLOBAL FOREIGN_KEY_CHECKS取消外键约束

    今天在工作中遇到的问题,在删除一个表时报错,发现有外键约束,所以不能删除,查了下发现需要取消外键约束. SET GLOBAL FOREIGN_KEY_CHECKS=0;全局取消外键约束 SET SES ...

  5. android API之android.text.TextWatcher

    When an object of a type is attached to an Editable, its methods will be called when the text is cha ...

  6. mysql中innodb和myisam的区别

    InnoDB和MyISAM是很多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,5.7之后就不一样了 1.事务和外键 InnoDB具有事务,支持4个事务隔离级别,回滚,崩溃修复能力和多版 ...

  7. Android 布局详解 -三表格布局(TableLayout)以及重要属性

              TableLayout跟TableRow 是一组搭配应用的布局,TableLayout置底,TableRow在TableLayout的上方,而Button.TextView等控件就 ...

  8. PLSQL_统计信息系列10_统计信息过旧导致程序出现性能问题

    2014-11-15 Created By BaoXinjian

  9. tomcat配置外部静态资源映射路径

    一.背景 1.有一个录音软件每天生成很多新的录音文件. 2.现在想通过一个WEB项目页面下载这些录音文件. 3.很显然这些录音文件放在WEB项目下不是很合适(WEB项目更新是个大麻烦,海量的录音文件要 ...

  10. C#--类之隐藏基类的成员

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...