显示标签为“BFS”的博文。显示所有博文
显示标签为“BFS”的博文。显示所有博文

2015年11月6日星期五

Leetcode 297 Serialize and Deserialize Binary Tree

Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.
For example, you may serialize the following tree
    1
   / \
  2   3
     / \
    4   5
as "[1,2,3,null,null,4,5]", just the same as how LeetCode OJ serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.
Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.
Solution 1: use recursive DFS, pre-order traversal.
 public class Codec {  
   // Encodes a tree to a single string.  
   public String serialize(TreeNode root) {  
     StringBuilder sb=new StringBuilder();  
     dfs(root,sb);  
     return sb.toString();  
   }  
   private void dfs(TreeNode x, StringBuilder sb) {  
     if (x==null) {  
       sb.append("null ");  
       return;  
     }  
     sb.append(String.valueOf(x.val));  
     sb.append(' ');  
     dfs(x.left,sb);  
     dfs(x.right,sb);  
   }  
   // Decodes your encoded data to tree.  
   public TreeNode deserialize(String data) {  
     String[] node=data.split(" ");  
     int[] d=new int[1];  
     return dfs(node,d);  
   }  
   private TreeNode dfs(String[] node, int[] d) {  
     if (node[d[0]].equals("null")) {  
       d[0]++;  
       return null;  
     }  
     TreeNode x=new TreeNode(Integer.valueOf(node[d[0]]));  
     d[0]++;  
     x.left=dfs(node,d);  
     x.right=dfs(node,d);  
     return x;  
   }  
 }  
Solution 2: Use iterative DFS, pre-order traversal.
 public class Codec {  
   // Encodes a tree to a single string.  
   public String serialize(TreeNode root) {  
     StringBuilder sb=new StringBuilder();  
     TreeNode x=root;  
     Deque<TreeNode> stack=new LinkedList<>();  
     while (x!=null || !stack.isEmpty()) {  
       if (x!=null) {  
         sb.append(String.valueOf(x.val));  
         sb.append(' ');  
         stack.push(x);  
         x=x.left;  
       }  
       else {  
         sb.append("null ");  
         x=stack.pop();  
         x=x.right;  
       }  
     }  
     return sb.toString();  
   }  
   // Decodes your encoded data to tree.  
   public TreeNode deserialize(String data) {  
     if (data.length()==0) return null;  
     String[] node=data.split(" ");  
     int n=node.length;  
     Deque<TreeNode> stack=new LinkedList<>();  
     TreeNode root=new TreeNode(Integer.valueOf(node[0]));  
     TreeNode x=root;  
     stack.push(x);  
     int i=1;  
     while (i<n) {  
       while (i<n && !node[i].equals("null")) {  
         x.left=new TreeNode(Integer.valueOf(node[i++]));  
         x=x.left;  
         stack.push(x);  
       }  
       while (i<n && node[i].equals("null")) {  
         x=stack.pop();  
         i++;  
       }  
       if (i<n) {  
         x.right=new TreeNode(Integer.valueOf(node[i++]));  
         x=x.right;  
         stack.push(x);  
       }  
     }  
     return root;  
   }  
 }  
Solution 3: Use BFS
 public class Codec {  
   // Encodes a tree to a single string.  
   public String serialize(TreeNode root) {  
     if (root==null) return "";  
     Queue<TreeNode> qu=new LinkedList<>();  
     StringBuilder sb=new StringBuilder();  
     qu.offer(root);  
     sb.append(String.valueOf(root.val));  
     sb.append(' ');  
     while (!qu.isEmpty()) {  
       TreeNode x=qu.poll();  
       if (x.left==null) sb.append("null ");  
       else {  
         qu.offer(x.left);  
         sb.append(String.valueOf(x.left.val));  
         sb.append(' ');  
       }  
       if (x.right==null) sb.append("null ");  
       else {  
         qu.offer(x.right);  
         sb.append(String.valueOf(x.right.val));  
         sb.append(' ');  
       }  
     }  
     return sb.toString();  
   }  
   // Decodes your encoded data to tree.  
   public TreeNode deserialize(String data) {  
     if (data.length()==0) return null;  
     String[] node=data.split(" ");  
     Queue<TreeNode> qu=new LinkedList<>();  
     TreeNode root=new TreeNode(Integer.valueOf(node[0]));  
     qu.offer(root);  
     int i=1;  
     while (!qu.isEmpty()) {  
       Queue<TreeNode> nextQu=new LinkedList<>();  
       while (!qu.isEmpty()) {  
         TreeNode x=qu.poll();  
         if (node[i].equals("null")) x.left=null;  
         else {  
           x.left=new TreeNode(Integer.valueOf(node[i]));  
           nextQu.offer(x.left);  
         }  
         i++;  
         if (node[i].equals("null")) x.right=null;  
         else {  
           x.right=new TreeNode(Integer.valueOf(node[i]));  
           nextQu.offer(x.right);  
         }  
         i++;  
       }  
       qu=nextQu;  
     }  
     return root;  
   }  
 }  

2015年11月5日星期四

Leetcode 286 Walls and Gates

You are given a m x n 2D grid initialized with these three possible values.
  1. -1 - A wall or an obstacle.
  2. 0 - A gate.
  3. INF - Infinity means an empty room. We use the value 231 - 1 = 2147483647 to represent INF as you may assume that the distance to a gate is less than2147483647.
Fill each empty room with the distance to its nearest gate. If it is impossible to reach a gate, it should be filled with INF.
For example, given the 2D grid:
INF  -1  0  INF
INF INF INF  -1
INF  -1 INF  -1
  0  -1 INF INF
After running your function, the 2D grid should be:
  3  -1   0   1
  2   2   1  -1
  1  -1   2  -1
  0  -1   3   4
Solution 1: Use BFS, store x*n+y in the queue for the node.
 public class Solution {  
   public void wallsAndGates(int[][] rooms) {  
     int m=rooms.length;  
     if (m==0) return;  
     int n=rooms[0].length;  
     Queue<Integer> q1=new LinkedList<>();  
     Queue<Integer> q2=new LinkedList<>();  
     for (int i=0; i<m; i++) {  
       for (int j=0; j<n; j++) {  
         if (rooms[i][j]==0) q1.offer(i*n+j);  
       }  
     }  
     int d=0;  
     while (!q1.isEmpty()) {  
       while (!q1.isEmpty()) {  
         int x=q1.poll();  
         int i=x/n, j=x%n;  
         helper(rooms,i+1,j,m,n,d,q2);  
         helper(rooms,i-1,j,m,n,d,q2);  
         helper(rooms,i,j+1,m,n,d,q2);  
         helper(rooms,i,j-1,m,n,d,q2);  
       }  
       Queue<Integer> temp=q1;  
       q1=q2;  
       q2=temp;  
       d++;  
     }  
   }  
   private void helper(int[][] rooms, int i, int j, int m, int n, int d, Queue<Integer> q2) {  
     if (i<0 || j<0 || i>=m || j>=n) return;  
     if (rooms[i][j]!=Integer.MAX_VALUE) return;  
     rooms[i][j]=d+1;  
     q2.offer(i*n+j);  
   }  
 }  

Leetcode 261 Graph Valid Tree

Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.
For example:
Given n = 5 and edges = [[0, 1], [0, 2], [0, 3], [1, 4]], return true.
Given n = 5 and edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]], return false.
Solution 1: Build the Graph then DFS
 public class Solution {  
   public boolean validTree(int n, int[][] edges) {  
     List<Integer>[] adj=new List[n];  
     for (int i=0; i<n; i++) adj[i]=new LinkedList<>();  
     for (int i=0; i<edges.length; i++) {  
       adj[edges[i][0]].add(edges[i][1]);  
       adj[edges[i][1]].add(edges[i][0]);  
     }  
     boolean[] marked=new boolean[n];  
     boolean[] hasCycle=new boolean[1];  
     dfs(adj,-1,0,hasCycle,marked);  
     for (int v=0; v<n; v++) {  
       if (!marked[v]) return false;  
     }  
     return !hasCycle[0];  
   }  
   private void dfs(List<Integer>[] adj, int s, int v, boolean[] hasCycle, boolean[] marked) {  
     marked[v]=true;  
     for (int w: adj[v]) {  
       if (hasCycle[0]) return;  
       else if (w!=s) {  
         if (!marked[w]) dfs(adj,v,w,hasCycle,marked);  
         else hasCycle[0]=true;  
       }  
     }  
   }  
 }  

Solution 2: Uni-Find
 public class Solution {  
   public boolean validTree(int n, int[][] edges) {  
     int[] nums=new int[n];  
     Arrays.fill(nums,-1);  
     for (int[] edge: edges) { //check loop  
       int x=edge[0], y=edge[1];  
       int c1=0, c2=0;  
       while (nums[x]!=-1) {  
         x=nums[x];  
         c1++;  
       }  
       while (nums[y]!=-1) {  
         y=nums[y];  
         c2++;  
       }  
       if (x==y) return false;  
       if (c1>c2) nums[y]=x;//connected small part to big part  
       else nums[x]=y;  
     }  
     int count=0; //check all connected, nums of -1 is nums of cc  
     for (int i=0; i<n; i++) {  
       if (nums[i]==-1 && ++count>1) return false;  
     }  
     return true;  
   }  
 }  

2015年10月24日星期六

Leetcode 199 Binary Tree Right Side View

Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.
For example:
Given the following binary tree,
   1            <---
 /   \
2     3         <---
 \     \
  5     4       <---
You should return [1, 3, 4].
Solution 1: Use BFS iterative is better way.
 public class Solution {  
   public List<Integer> rightSideView(TreeNode root) {  
     List<Integer> res=new ArrayList<>();  
     if (root==null) return res;  
     Deque<TreeNode> qu=new LinkedList<>();  
     Deque<TreeNode> next=new LinkedList<>();  
     qu.offer(root);  
     while (!qu.isEmpty()) {  
       TreeNode x=null;  
       while (!qu.isEmpty()) {  
         x=qu.poll();  
         if (x.left!=null) next.offer(x.left);  
         if (x.right!=null) next.offer(x.right);  
       }  
       res.add(x.val);  
       Deque<TreeNode> temp=qu;  
       qu=next;  
       next=temp;  
     }  
     return res;  
   }  

2015年10月12日星期一

Leetcode 138 Copy List with Random Pointer

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
Return a deep copy of the list.
Solution 1: use graph copy method, it can deal with the random list even it has loop. Below is an example of BFS.
 public class Solution {  
   public RandomListNode copyRandomList(RandomListNode head) {  
     if (head==null) return null;  
     Map<RandomListNode,RandomListNode> map=new HashMap<>();  
     Queue<RandomListNode> qu=new LinkedList<>();  
     RandomListNode x=new RandomListNode(head.label);  
     map.put(head,x);  
     qu.offer(head);  
     while (!qu.isEmpty()) {  
       RandomListNode v=qu.poll();  
       if (v.next!=null && !map.containsKey(v.next)) {  
         RandomListNode w1=new RandomListNode(v.next.label);  
         map.put(v.next,w1);  
         qu.offer(v.next);  
       }  
       if (v.random!=null && !map.containsKey(v.random)) {  
         RandomListNode w2=new RandomListNode(v.random.label);  
         map.put(v.random,w2);  
         qu.offer(v.random);  
       }  
       if (v.next!=null) map.get(v).next=map.get(v.next);  
       if (v.random!=null) map.get(v).random=map.get(v.random);  
     }  
     return map.get(head);  
   }  
 }  

Solution 2: if we know that there is no loop. Code can be much cleaner.
 public class Solution {  
   public RandomListNode copyRandomList(RandomListNode head) {  
     if (head==null) return null;  
     Map<RandomListNode,RandomListNode> map=new HashMap<>();  
     RandomListNode x=head;  
     while (x!=null) {  
       RandomListNode w=new RandomListNode(x.label);  
       map.put(x,w);  
       x=x.next;  
     }  
     x=head;  
     while (x!=null) {  
       map.get(x).next=map.get(x.next);  
       map.get(x).random=map.get(x.random);  
       x=x.next;  
     }  
     return map.get(head);  
   }  
 }  

Leetcode 133 Clone Graph

Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.

OJ's undirected graph serialization:
Nodes are labeled uniquely.
We use # as a separator for each node, and , as a separator for node label and each neighbor of the node.
As an example, consider the serialized graph {0,1,2#1,2#2,2}.
The graph has a total of three nodes, and therefore contains three parts as separated by #.
  1. First node is labeled as 0. Connect node 0 to both nodes 1 and 2.
  2. Second node is labeled as 1. Connect node 1 to node 2.
  3. Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle.
Visually, the graph looks like the following:
       1
      / \
     /   \
    0 --- 2
         / \
         \_/
Solution 1: Recursive dfs. O(E)
 public class Solution {  
   public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {  
     if (node==null) return null;  
     Map<UndirectedGraphNode,UndirectedGraphNode> map=new HashMap<>();  
     dfs(map,node);  
     return map.get(node);  
   }  
   private void dfs(Map<UndirectedGraphNode,UndirectedGraphNode> map, UndirectedGraphNode v) {  
     UndirectedGraphNode x=new UndirectedGraphNode(v.label);  
     map.put(v,x);  
     for (UndirectedGraphNode w: v.neighbors) {  
       if (!map.containsKey(w)) dfs(map,w);  
       x.neighbors.add(map.get(w));  
     }  
   }  
 }  

Solution 2: BFS
 public class Solution {  
   public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {  
     if (node==null) return null;  
     Queue<UndirectedGraphNode> qu=new LinkedList<>();  
     Map<UndirectedGraphNode, UndirectedGraphNode> map=new HashMap<>();  
     UndirectedGraphNode x=new UndirectedGraphNode(node.label);  
     map.put(node,x);  
     qu.offer(node);  
     while (!qu.isEmpty()) {  
       UndirectedGraphNode v=qu.poll();  
       for (UndirectedGraphNode w: v.neighbors) {  
         if (!map.containsKey(w)) {  
           map.put(w, new UndirectedGraphNode(w.label));  
           qu.offer(w);  
         }  
         map.get(v).neighbors.add(map.get(w));  
       }  
     }  
     return map.get(node);  
   }  
 }  

2015年10月8日星期四

Leetcode 130 Surrounded Regions

Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'.
A region is captured by flipping all 'O's into 'X's in that surrounded region.
For example,
X X X X
X O O X
X X O X
X O X X
After running your function, the board should be:
X X X X
X X X X
X X X X
X O X X
Solution 1: Use recursive DFS will get system stack overflow when board is huge. Use BFS and queue is better way.
 public class Solution {  
   public void solve(char[][] board) {  
     int m=board.length;  
     if (m==0) return;  
     int n=board[0].length;  
     Queue<List<Integer>> qu=new LinkedList<>();  
     for (int j=0; j<n; j++) {  
       if (board[0][j]=='O') {board[0][j]='T'; qu.offer(Arrays.asList(0,j));}  
       if (board[m-1][j]=='O') {board[m-1][j]='T'; qu.offer(Arrays.asList(m-1,j));}  
     }  
     for (int i=1; i<m-1; i++) {  
       if (board[i][0]=='O') {board[i][0]='T'; qu.offer(Arrays.asList(i,0));}  
       if (board[i][n-1]=='O') {board[i][n-1]='T'; qu.offer(Arrays.asList(i,n-1));}  
     }  
     while (!qu.isEmpty()) {  
       List<Integer> one=qu.poll();  
       int i=one.get(0), j=one.get(1);  
       check(board,i+1,j,m,n,qu);  
       check(board,i-1,j,m,n,qu);  
       check(board,i,j+1,m,n,qu);  
       check(board,i,j-1,m,n,qu);  
     }  
     for (int i=0; i<m; i++) {  
       for (int j=0; j<n; j++) {  
         if (board[i][j]=='O') board[i][j]='X';  
         if (board[i][j]=='T') board[i][j]='O';  
       }  
     }  
   }  
   private void check(char[][] board, int i, int j, int m, int n, Queue<List<Integer>> qu) {  
     if (i<0 || i>=m || j<0 || j>=n) return;  
     if (board[i][j]!='O') return;  
     board[i][j]='T';  
     qu.offer(Arrays.asList(i,j));  
   }  
 }  

Leetcode 127 Word Ladder

Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:
  1. Only one letter can be changed at a time
  2. Each intermediate word must exist in the word list
For example,
Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.
Note:
  • Return 0 if there is no such transformation sequence.
  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
Solution 1: Use BFS and a set to track each ladder with solve it. 
 public class Solution {  
   public int ladderLength(String beginWord, String endWord, Set<String> wordList) {  
     Set<String> set=new HashSet<>();  
     set.add(beginWord);  
     int d=0;  
     while (!set.isEmpty()) {  
       wordList.removeAll(set);  
       Set<String> nextSet=new HashSet<>();  
       for (String s:set) {  
         char[] c=s.toCharArray();  
         for (int i=0; i<c.length; i++) {  
           char temp=c[i];  
           for (char r='a'; r<='z'; r++) {  
             c[i]=r;  
             String x=new String(c);  
             if (x.equals(endWord)) return d+2;  
             else if (wordList.contains(x)) nextSet.add(x);  
           }  
           c[i]=temp;  
         }  
       }  
       set=nextSet;  
       d++;  
     }  
     return 0;  
   }  
 }  

Leetcode 126 Word Ladder II

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:
  1. Only one letter can be changed at a time
  2. Each intermediate word must exist in the word list
For example,
Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
Return
  [
    ["hit","hot","dot","dog","cog"],
    ["hit","hot","lot","log","cog"]
  ]
Note:
  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
Solution 1: The assumption is that the dictionary is huge and word itself is short, so we can not search the wordList, but change the each letter at one time then look up if it exist in the dictionary. The algorithm is to use BFS to build a graph, then do DFS to get the whole list. Use set to track each level of the ladder (like queue in BFS).
 public class Solution {  
   public List<List<String>> findLadders(String beginWord, String endWord, Set<String> wordList) {  
     Map<String,List<String>> map=new HashMap<>();  
     Set<String> set=new HashSet<>();  
     set.add(beginWord);  
     boolean found=false;  
     while (!found && !set.isEmpty()) {  
       wordList.removeAll(set);  
       Set<String> nextSet=new HashSet<>();  
       for (String s:set) {  
         List<String> adj=new ArrayList<>();  
         char[] c=s.toCharArray();  
         for (int i=0; i<c.length; i++) {  
           char temp=c[i];  
           for (char r='a'; r<='z'; r++) {  
             c[i]=r;  
             String x=new String(c);  
             if (x.equals(endWord)) {  
               found=true;  
               adj.add(x);  
             }  
             else if (wordList.contains(x)) {  
               adj.add(x);  
               nextSet.add(x);  
             }  
           }  
           c[i]=temp;  
         }  
         map.put(s,adj);  
       }  
       set=nextSet;  
     }  
     List<List<String>> res=new ArrayList<>();  
     List<String> one=new ArrayList<>();  
     dfs(map,beginWord,endWord,one,res);  
     return res;  
   }  
   private void dfs(Map<String,List<String>> map, String s, String endWord, List<String> one, List<List<String>> res) {  
     one.add(s);  
     if (s.equals(endWord)) res.add(new ArrayList<String>(one));  
     else if (map.containsKey(s)) {  
       for (String x:map.get(s)) dfs(map,x,endWord,one,res);  
     }  
     one.remove(one.size()-1);  
   }  
 }  
Solution 2: Optimize use 2 sets and search from both begin and end. Use the smaller set to perform next step. Run time 36 ms.
 public class Solution {  
   public List<List<String>> findLadders(String beginWord, String endWord, Set<String> wordList) {  
     Set<String> set1=new HashSet<>();  
     Set<String> set2=new HashSet<>();  
     Map<String,List<String>> map=new HashMap<>();  
     set1.add(beginWord);  
     set2.add(endWord);  
     boolean dir=true, found=false;  
     while (!found && !set1.isEmpty() && !set2.isEmpty()) { //set can not be empty, otherwise in dead loop  
       if (set1.size()>set2.size()) {  
         Set<String> temp=set1;  
         set1=set2;  
         set2=temp;  
         dir=!dir;  
       }  
       wordList.removeAll(set1);  
       Set<String> nextSet=new HashSet<>();  
       for (String word: set1) {  
         char c[]=word.toCharArray();  
         for (int i=0; i<c.length; i++) {  
           char org=c[i];  
           for (char r='a'; r<='z'; r++) {  
             c[i]=r;  
             String s=new String(c);  
             if (set2.contains(s) || wordList.contains(s)) {  
               if (set2.contains(s)) found=true;  
               String key=dir?word:s;  
               String value=dir?s:word;  
               if (map.containsKey(key)) map.get(key).add(value);  
               else {  
                 List<String> list=new LinkedList<>();  
                 list.add(value);  
                 map.put(key,list);  
               }  
               nextSet.add(s);  
             }  
           }  
           c[i]=org;  
         }  
       }  
       set1=nextSet;  
     }  
     List<String> one=new ArrayList<>();  
     List<List<String>> res=new ArrayList<>();  
     dfs(map,beginWord,endWord,one,res);  
     return res;  
   }  
   private void dfs(Map<String,List<String>> map, String word, String endWord, List<String> one, List<List<String>> res) {  
     one.add(word);  
     if (word.equals(endWord)) res.add(new ArrayList<String>(one));  
     else if (map.containsKey(word)) { // pay attention here  
       for (String s: map.get(word)) dfs(map,s,endWord,one,res);  
     }  
     one.remove(one.size()-1);  
   }  
 }  

2015年10月6日星期二

Leetcode 117 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: same as leetcode 116, use BFS and use next link as the queue.
 public class Solution {  
   public void connect(TreeLinkNode root) {  
     if (root==null) return;  
     TreeLinkNode head=root;  
     TreeLinkNode dummy=new TreeLinkNode(0);  
     while (head!=null) {  
       TreeLinkNode p=dummy;  
       while (head!=null) {  
         if (head.left!=null) {  
           p.next=head.left;  
           p=p.next;  
         }  
         if (head.right!=null) {  
           p.next=head.right;  
           p=p.next;  
         }  
         head=head.next;  
       }  
       head=dummy.next;  
       dummy.next=null;  
     }  
   }  
 }  

Leetcode 116 Populating Next Right Pointers in Each Node

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: Use the next list as the queue to do BFS, so no need for extra space.
 public class Solution {  
   public void connect(TreeLinkNode root) {  
     if (root==null) return;  
     TreeLinkNode head=root;  
     TreeLinkNode dummy=new TreeLinkNode(0);  
     while (head!=null) {  
       TreeLinkNode p=dummy;  
       while (head!=null) {  
         if (head.left!=null) {  
           p.next=head.left;  
           p=p.next;  
         }  
         if (head.right!=null) {  
           p.next=head.right;  
           p=p.next;  
         }  
         head=head.next;  
       }  
       head=dummy.next;  
       dummy.next=null;  
     }  
   }  
 }  

2015年10月4日星期日

Leetcode 107 Binary Tree Level Order Traversal II

Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).
For example:
Given binary tree {3,9,20,#,#,15,7},
    3
   / \
  9  20
    /  \
   15   7
return its bottom-up level order traversal as:
[
  [15,7],
  [9,20],
  [3]
]
Solution 1: iterative BFS
 public class Solution {  
   public List<List<Integer>> levelOrderBottom(TreeNode root) {  
     List<List<Integer>> res=new LinkedList<>();  
     Queue<TreeNode> q1=new LinkedList<>();  
     Queue<TreeNode> q2=new LinkedList<>();  
     if (root==null) return res;  
     q1.offer(root);  
     while (!q1.isEmpty()) {  
       List<Integer> one=new ArrayList<>();  
       while (!q1.isEmpty()) {  
         TreeNode x=q1.poll();  
         one.add(x.val);  
         if (x.left!=null) q2.offer(x.left);  
         if (x.right!=null) q2.offer(x.right);  
       }  
       res.add(0,one);  
       Queue<TreeNode> temp=q1;  
       q1=q2;  
       q2=temp;  
     }  
     return res;  
   }  
 }  

Solution 2: Recursive DFS, compare to BFS version, the insertion of new line cost is high.
 public class Solution {  
   public List<List<Integer>> levelOrderBottom(TreeNode root) {  
     List<List<Integer>> res=new ArrayList<>();  
     dfs(root,0,res);  
     return res;  
   }  
   private void dfs(TreeNode x, int d, List<List<Integer>> res) {  
     if (x==null) return;  
     if (d==res.size()) res.add(0,new ArrayList<Integer>());//cost high for ArrayList  
     res.get(res.size()-d-1).add(x.val);//cost low, happen more frequently  
     dfs(x.left,d+1,res);  
     dfs(x.right,d+1,res);  
   }  
 }  

2015年10月3日星期六

Leetcode 103 Binary Tree Zigzag Level Order Traversal

Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between).
For example:
Given binary tree {3,9,20,#,#,15,7},
    3
   / \
  9  20
    /  \
   15   7
return its zigzag level order traversal as:
[
  [3],
  [20,9],
  [15,7]
]
Solution 1: iterative BFS use stack
 public class Solution {  
   public List<List<Integer>> zigzagLevelOrder(TreeNode root) {  
     Deque<TreeNode> s1=new LinkedList<>();  
     Deque<TreeNode> s2=new LinkedList<>();  
     List<List<Integer>> res=new ArrayList<>();  
     if (root==null) return res;  
     s1.push(root);  
     while (!s1.isEmpty()) {  
       List<Integer> one=new ArrayList<>();  
       while (!s1.isEmpty()) {  
         TreeNode x=s1.pop();  
         one.add(x.val);  
         if (x.left!=null) s2.push(x.left);  
         if (x.right!=null) s2.push(x.right);  
       }  
       res.add(one);  
       if (s2.isEmpty()) break;  
       List<Integer> two=new ArrayList<>();  
       while (!s2.isEmpty()) {  
         TreeNode x=s2.pop();  
         two.add(x.val);  
         if (x.right!=null) s1.push(x.right);  
         if (x.left!=null) s1.push(x.left);  
       }  
       res.add(two);  
     }  
     return res;  
   }  
 }  

Solution 2: recursive using DFS
 public class Solution {  
   public List<List<Integer>> zigzagLevelOrder(TreeNode root) {  
     List<List<Integer>> res=new ArrayList<>();  
     dfs(root,0,res);  
     return res;  
   }  
   private void dfs(TreeNode x, int d, List<List<Integer>> res) {  
     if (x==null) return;  
     if (d==res.size()) res.add(new LinkedList<Integer>());  
     if (d%2==0) res.get(d).add(x.val);  
     else res.get(d).add(0,x.val);  
     dfs(x.left,d+1,res);  
     dfs(x.right,d+1,res);  
   }  
 }  

2015年10月2日星期五

Leetcode 102 Binary Tree Level Order Traversal

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]
]
Solution 1: recursive DFS
 public class Solution {  
   public List<List<Integer>> levelOrder(TreeNode root) {  
     List<List<Integer>> res=new ArrayList<>();  
     dfs(root,0,res);  
     return res;  
   }  
   private void dfs(TreeNode x, int d, List<List<Integer>> res) {  
     if (x==null) return;  
     if (d==res.size()) res.add(new ArrayList<Integer>());  
     res.get(d).add(x.val);  
     dfs(x.left,d+1,res);  
     dfs(x.right,d+1,res);  
   }  
 }  

Solution 2: iterative BFS
 public class Solution {  
   public List<List<Integer>> levelOrder(TreeNode root) {  
     List<List<Integer>> res=new ArrayList<>();  
     if (root==null) return res;  
     Queue<TreeNode> q1=new LinkedList<>();  
     Queue<TreeNode> q2=new LinkedList<>();  
     q1.offer(root);  
     while (!q1.isEmpty()) {  
       List<Integer> one=new ArrayList<>();  
       while (!q1.isEmpty()) {  
         TreeNode x=q1.poll();  
         one.add(x.val);  
         if (x.left!=null) q2.offer(x.left);  
         if (x.right!=null) q2.offer(x.right);  
       }  
       res.add(one);  
       q1=q2;  
       q2=new LinkedList<>();  
     }  
     return res;  
   }  
 }