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 ...
随机推荐
- 引入css的几种方式
使用CSS样式的几种方式 CreateTime--2017年10月11日16:45:26 Author:Marydon a.外部样式 a1.链接式(推荐使用) <link href=&quo ...
- SDUT 1157-小鼠迷宫问题(BFS&DFS)
小鼠迷宫问题 nid=24#time" title="C.C++.go.haskell.lua.pascal Time Limit1500ms Memory Limit 65536 ...
- (39)JS运动之缓冲运动
基本思路:使用定时器让物体向右运动,在运动的过程中再不是匀速运动,而是先快后慢,即距离越大,速度越快,距离越小,速度越小,可是到达终点的时候,必须注意要使用向上取整函数Math.ceil()和向下取整 ...
- Google 做过的 12 件奇葩事
Google做了太多伟大的事情了.以至于有时它有点让人难以实时跟上它的动态.假设你对这家公司略微有点感情.看看他们做过的一些有点匪夷所思的事儿,可能认为,毕竟是大公司.还挺难以被全然理解透的. 一个Q ...
- mermaid 语法
a:focus { outline: thin dotted #333; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2p ...
- RabbitMQ消息队列(五):Routing 消息路由 2[原]
上一篇文章使用的是Direct的Exchange,但是没有指定Queue的名字,这样只能是先运行Consumer之后,Producer在运行发消息Consumer才能收到,否则先运行Producer发 ...
- 解决LLDB模式下出现message sent to deallocated instance错误
本文在源文的基础上做整理:http://www.devdiv.com/home.php?mod=space&uid=50901&do=blog&id=50856 Xcode版本 ...
- Sourcetree 更新git账号密码
删除Sourcetree 缓存文件(只需要删密码文件),文件位置: Mac: ~/Library/Application Support/SourceTree Windows: C:\Users\US ...
- C 标准库IO缓冲区和内核缓冲区的区别
1.C标准库的I/O缓冲区 UNIX的传统 是Everything is a file,键盘.显示器.串口.磁盘等设备在/dev 目录下都有一个特殊的设备文件与之对应,这些设备文件也 ...
- NYOJ239 月老的难题 【二分图最大匹配·匈牙利】
月老的难题 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描写叙述 月老准备给n个女孩与n个男孩牵红线.成就一对对美好的姻缘. 如今,因为一些原因,部分男孩与女孩可能结成幸福 ...