Given a binary tree, return the level order traversal of its nodes’ values. (ie, from left to right, level by level).
For example:
Given binary tree {3,9,20,#,#,15,7},
3 / \ 9 20 / \ 15 7
return its level order traversal as [[3], [9,20], [15,7]]
Java Solution 1
It is obvious that this problem can be solve by using a queue. However, if we use one queue we can not track when each level starts. So we use two queues to track the current level and the next level.
public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) { ArrayList<ArrayList<Integer>> al = new ArrayList<ArrayList<Integer>>(); ArrayList<Integer> nodeValues = new ArrayList<Integer>(); if(root == null) return al; LinkedList<TreeNode> current = new LinkedList<TreeNode>(); LinkedList<TreeNode> next = new LinkedList<TreeNode>(); current.add(root); while(!current.isEmpty()){ TreeNode node = current.remove(); if(node.left != null) next.add(node.left); if(node.right != null) next.add(node.right); nodeValues.add(node.val); if(current.isEmpty()){ current = next; next = new LinkedList<TreeNode>(); al.add(nodeValues); nodeValues = new ArrayList(); } } return al; } |
Java Solution 2
We can also improve Solution 1 by use a queue of integer to track the level instead of track another level of nodes.
public List<List<Integer>> levelOrder(TreeNode root) { List<List<Integer>> result = new ArrayList<>(); if(root==null){ return result; } LinkedList<TreeNode> nodeQueue = new LinkedList<>(); LinkedList<Integer> levelQueue = new LinkedList<>(); nodeQueue.offer(root); levelQueue.offer(1);//start from 1 while(!nodeQueue.isEmpty()){ TreeNode node = nodeQueue.poll(); int level = levelQueue.poll(); List<Integer> l=null; if(result.size()<level){ l = new ArrayList<>(); result.add(l); }else{ l = result.get(level-1); } l.add(node.val); if(node.left!=null){ nodeQueue.offer(node.left); levelQueue.offer(level+1); } if(node.right!=null){ nodeQueue.offer(node.right); levelQueue.offer(level+1); } } return result; } |
Good code, and the most efficient one i’ve found. Those searching around here’s the updated version.
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
//undestand traveersal of bst, inorder pre, and post. use of enqueue and deque operations
class Solution {
public List<List> levelOrder(TreeNode root) {
List<List> result = new ArrayList();
if (root == null)
return result;
LinkedList queue = new LinkedList();
queue.add(root);
while (!queue.isEmpty()) {
int size = queue.size();
ArrayList l = new ArrayList(size);
for (int i = 0; i < size ; i++) {
TreeNode n = queue.remove();
l.add(n.val);
if (n.left != null)
queue.add(n.left);
if (n.right != null)
queue.add(n.right);
}
result.add(l);
}
return result;
}
}
tnx for posting, great sol; excpet u may wanna change list -> List, integer -> Integer
Maybe this should be reviewed… later on (@Binary Tree Right Side View) there is a simpler (cleaner) solution.
Basically, you don’t need 2 queues… one seems to be enough.
List<List> levelOrder(Node root) {
List<List> result = new ArrayList();
if (root == null)
return result;
LinkedList queue = new LinkedList();
queue.add(root);
while (!queue.isEmpty()) {
int size = queue.size();
ArrayList l = new ArrayList(size);
for (int i = 0; i < size ; i++) {
Node n = queue.remove();
l.add(n.value);
if (n.left != null)
queue.add(n.left);
if (n.right != null)
queue.add(n.right);
}
result.add(l);
}
return result;
}
Sorry!
My code is just displaying Trees in level order.
private static void levelOrder(Node root) {
if (root == null)
return;
Queue queue = new LinkedList();
Node curr = root;
queue.add(curr);
while (!queue.isEmpty()) {
Node node = queue.remove();
System.out.print(node.data + " ");
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
}
Another One queue solution.
public class Solution {
public List<List> levelOrder(TreeNode root) {
TreeNode tmp = new TreeNode(Integer.MIN_VALUE);
List<List> result = new ArrayList<List>();
if(root == null){
return result;
}else{
Queue queue = new LinkedList();
queue.add(root);
queue.add(tmp);
while(!queue.isEmpty() && queue.peek() != tmp){
List r = new ArrayList();
while(queue.peek() != tmp){
TreeNode t = queue.poll();
r.add(t.val);
if(t.left!=null){
queue.add(t.left);
}
if(t.right!=null){
queue.add(t.right);
}
}
queue.poll();
queue.add(tmp);
result.add(r);
}
}
return result;
}
}
Dont need 2 queues. One is enough.
Key is to have a good exit condition.
public List<List> levelOrder(TreeNode root) {
List<List> list = new ArrayList<List>();
List l1 = new ArrayList();
if(null == root){
return list;
}
Queue q = new LinkedList();
q.offer(root);
q.offer(null);
while(!q.isEmpty()){
TreeNode top = q.poll();
if(null != top){
l1.add(top.val);
if(null != top.left){
q.offer(top.left);
}
if(null != top.right ){
q.offer(top.right);
}
}else{
list.add(l1);
l1 = new ArrayList();
q.offer(null);
}
if (null == top && null == q.peek()){
break;
}
}
return list;
}
Another solution with one queue
public List<List> levelOrder(TreeNode root) {
List<List> results = new ArrayList<List>();
if(root == null)
return results;
List levelResult = new ArrayList();
Queue queue = new LinkedList();
queue.offer(root);
queue.offer(null);
TreeNode node = null;
while(! queue.isEmpty()){
node = queue.poll();
if(node != null){
levelResult.add(node.val);
}
if(queue.size() > 0 && node == null){
results.add(levelResult);
levelResult = new ArrayList();
queue.offer(null);
}
if(node!=null && node.left != null){
queue.offer(node.left);
}
if(node != null && node.right != null){
queue.offer(node.right);
}
}
results.add(levelResult);
return results;
}
Solution with one queue only.
public List<List> levelOrder(TreeNode root) {
//queue will handle this
List<List> result = new ArrayList();
Queue q = new LinkedList();
if(root == null) return result;
List list = new ArrayList();
q.add(root);
TreeNode rightMost = root;
//this is for the case that the right most doesnt have child nodes, so we need to keep track of the
TreeNode b = null;
while(!q.isEmpty()){
TreeNode t = q.remove();
list.add(t.val);
if(t == rightMost){
result.add(list);
list = new ArrayList();
if(t.right != null) rightMost = t.right;
else if(t.left != null) rightMost = t.left;
else rightMost = b;
}
if(t.left != null){
q.add(t.left);
b = t.left;
}
if(t.right != null){
q.add(t.right);
b = t.right;
}
}
return result;
}