LeetCode: Populating Next Right Pointers in Each Node II 解题报告
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
LeetCode: Populating Next Right Pointers in Each Node II 解题报告的更多相关文章
- 【LeetCode】117. Populating Next Right Pointers in Each Node II 解题报告(Python)
[LeetCode]117. Populating Next Right Pointers in Each Node II 解题报告(Python) 标签: LeetCode 题目地址:https:/ ...
- [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 ...
- 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 ...
- [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 ...
- LeetCode - Populating Next Right Pointers in Each Node II
题目: Follow up for problem "Populating Next Right Pointers in Each Node". What if the given ...
- [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 ...
- 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 ...
- 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 ...
- [LeetCode] Populating Next Right Pointers in Each Node 每个节点的右向指针
Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *nex ...
随机推荐
- [C#]记录程序耗时的方法【转发】
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); // H ...
- System.out.print实现原理猜解
我们往往在main中直接调用System.out.print方法来打印,但是其实就这简单的一步里面有很多的玄机,因为main是static的,所以只能调用static的函数,那么print是stati ...
- jQuery动态表格插件 AppendGrid
AppendGrid是一个jQuery动态表格插件,提供像填写电子表格数据一样在页面去输入结构化数据. 它允许用户在表格里增加/删除/插入/删除行,控制input/select/textarea 提交 ...
- Xcode8的调试技能Memory Graph 实战解决闭包引用循环问题
Xcode8的调试技能又增加了一个黑科技:Memory Graph.简单的说就是可以在运行时将内存中的对象生成一张图. 那么通过一个实际项目来练习一下吧. 首先我们写了一个自定义UIView:MyVi ...
- SpringBoot优化内嵌的Tomcat ---设置MaxConnections
使用kill -9杀掉springboot应用后,立马java -jar重启,会报错,需要等待一段时间才能启动成功,报错的原因是:/tmp/tomcat-docbase.474979491043437 ...
- 1.Java基础-面向对象编程思想(封装继承多态接口)
封装: 1.定义:隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别. 2.封装的目的是:增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,一特定的 ...
- 在rhel6上安装Python 2.7和Python 3.3
安装前,操作系统软件包准备编译python要安装development tools.此外,还要安装一些其他的libs,没有这些libs,python的interpreter可能会无法正常工作 # yu ...
- PLSQL_性能优化索引Index介绍(概念)
2014-06-01 BaoXinjian
- Android判断当前网络是否可用--示例代码
Android判断当前网络是否可用--示例代码 分类: *07 Android 2011-05-24 13:46 7814人阅读 评论(4) 收藏 举报 网络androiddialogmanagern ...
- Linux内核同步 - sleepable RCU的实现
一.前言 由于曾经在Linux2.6.23上工作了多年,我对这个版本还是非常有感情的(抛开感情因素,本来应该选择longterm的2.6.32版本来分析的,^_^),本文主要就是描述Linux2.6. ...