leetcode Question 24: Convert Sorted List to Binary Search Tree

Convert Sorted List to Binary Search Tree


Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.



Analysis:



The easier way to solve this problem is use the idea as the previous one.
Here present another way of thinking.
In the previous array to BST, we construct the BST in a top-down way. For the list data structure, to get the mid point every time is a waster of time. So construct the BST in a bottom-up way. However, the length of the list must be computed.

Recursively 
1. construct the left tree 
2. construct the root node, list pointer +1.
3. construct the right node

Note that in Python, the function argument is more like a "pass by value" way if the argument is immutable, to use the C++ like "pass by reference", the argument should be a mutable type, here in the code, a list of "ListNode" is used.

Code(C++):





/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:

    TreeNode *l2bst(ListNode* &head,int st, int ed){
        if (st>ed) {return NULL;}
        TreeNode *lefttree = l2bst(head,st,int(st+(ed-st)/2)-1);
        TreeNode *parent = new TreeNode(head->val); 
        head = head->next;
        TreeNode *righttree = l2bst(head,int(st+(ed-st)/2)+1,ed);
        parent->left  = lefttree;
        parent->right  = righttree;
        return parent;
    }
    
    TreeNode *sortedListToBST(ListNode *head) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (head==NULL){return NULL;}
        ListNode *h=head;
        int len = 0;
        while (h){
            len = len+1;
            h = h->next;
        }
        TreeNode *root=l2bst(head,1,len);
        return root;

    }
};


Code(Python):

# Definition for a  binary tree node
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    # @param head, a list node
    # @return a tree node
    def bst(self, head, st, ed):
        if st > ed or head[0] == None:
            return None
        mid = st + (ed - st)/2
        left = self.bst(head, st, mid - 1)
        root = TreeNode(head[0].val)
        head[0] = head[0].next
        right = self.bst(head, mid + 1, ed)
        root.left = left
        root.right = right
        return root

    def sortedListToBST(self, head):
        if head == None: 
            return None
        tmp = head
        n = 0
        while tmp != None:
            n += 1
            tmp = tmp.next
        return self.bst([head], 0, n)
        
        
        

leetcode Question 23: Convert Sorted Array to Binary Search Tree

Convert Sorted Array to Binary Search Tree


Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.




Analysis:


Because the requirement "height balanced", this problem becomes relative easy.
Just recursively use the middle element in the array as the root node of the current tree(sub tree).



Code(C++):




/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:

    TreeNode* cbst(vector<int> &num, int st, int ed){
        if (st>ed){
            return NULL;
        }else{
            int mid = st+(ed-st)/2;
            TreeNode *bst=new TreeNode(num[mid]);
            bst->left = cbst(num,st,mid-1);
            bst->right = cbst(num,mid+1,ed);
            return bst;
        }
    }

    TreeNode *sortedArrayToBST(vector<int> &num) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (num.size()==0){return NULL;}
        return cbst(num,0,num.size()-1);
    }
};


Code(Python):

# Definition for a  binary tree node
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    # @param num, a list of integers
    # @return a tree node
    def bst(self, num, st, ed):
        if st > ed:
            return None
        mid = st + (ed - st)/2
        left = self.bst(num, st, mid - 1)
        root = TreeNode(num[mid])
        right = self.bst(num, mid + 1, ed)
        root.left = left
        root.right = right
        return root
    
    def sortedArrayToBST(self, num):
        n = len(num)
        if n == 0:
            return None
        return self.bst(num, 0, n-1)
        

leetcode Question 22: Container With Most Water


Container With Most Water
Given n non-negative integers a1a2, ..., an, where each represents a point at coordinate (iai). n vertical lines are drawn such that the two endpoints of line i is at (iai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container.


Analysis:
An easy but time-consuming way to solve this problem is of O(n^2), compare the area for each pair of points. However, it cannot pass the large test.
There is a greedy way to solve this problem in O(n). Use two pointers, one from the start and one from the end of the height vector. Compute the current area, move the smaller pointer to its direction, until two pointers meet.

The source code of O(n^2) method:
class Solution {
public:
    int maxArea(vector<int> &height) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int maxa = 0;
        if (height.size()<2){return maxa;}
        for (int i = 1; i<height.size();i++){
            for(int j = 0; j<i ; j++){
                int ar = abs(i-j)*min(height[i],height[j]);
                if (ar>maxa){ maxa = ar;}
            }
        }
        return maxa;
    }
};


The source code O(n):
class Solution {
public:
    int maxArea(vector<int> &height) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int maxa = 0;
        if (height.size()<2){return maxa;}
        int l = 0;
        int r = height.size()-1;
        
        while (l<r){
            int ar = abs(l-r)*min(height[l],height[r]);
            if (ar>maxa){ maxa = ar;}
            
            if(height[l]<=height[r]) { l = l+1;}
            else {r= r-1;}
        }
        
        
        return maxa;
    }
};

leetcode Question Index

Blue:  Completed (Passed both small and large online judges)
Black: Not Completed


Newer Questions:
126 Valid Palindrome
127 Word Ladder
128 Word Ladder II
129 Longest Consecutive Sequence
130 Sum Root to Leaf Numbers
131 Surrounded Regions
132 Palindrome Partitioning 
133 Palindrome Partitioning II



1 3Sum
2 3Sum Closest
3 4Sum
4 Add Binary
5 Add Two Numbers
6 Anagrams
7 Balanced Binary Tree
8 Best Time to Buy and Sell Stock
9 Best Time to Buy and Sell Stock II
10 Best Time to Buy and Sell Stock III
11 Binary Tree Inorder Traversal
12 Binary Tree Level Order Traversal
13 Binary Tree Level Order Traversal II
14 Binary Tree Maximum Path Sum
15 Binary Tree Zigzag Level Order Traversal
16 Climbing Stairs
17 Combination Sum
18 Combination Sum II
19 Combinations
20 Construct Binary Tree from Inorder and Postorder Traversal
21 Construct Binary Tree from Preorder and Inorder Traversal
22 Container With Most Water
23 Convert Sorted Array to Binary Search Tree
24 Convert Sorted List to Binary Search Tree
25 Count and Say
26 Decode Ways
27 Distinct Subsequences
28 Divide Two Integers
29 Edit Distance
30 First Missing Positive
31 Flatten Binary Tree to Linked List
32 Generate Parentheses
33 Gray Code
34 Implement strStr()
35 Insert Interval
36 Integer to Roman
37 Interleaving String
38 Jump Game
39 Jump Game II
40 Largest Rectangle in Histogram
41 Length of Last Word
42 Letter Combinations of a Phone Number
43 Longest Common Prefix
44 Longest Palindromic Substring
45 Longest Substring Without Repeating Characters
46 Longest Valid Parentheses
47 Maximal Rectangle
48 Maximum Depth of Binary Tree
49 Maximum Subarray
50 Median of Two Sorted Arrays
51 Merge Intervals
52 Merge k Sorted Lists
53 Merge Sorted Array
54 Merge Two Sorted Lists
55 Minimum Depth of Binary Tree
56 Minimum Path Sum
57 Minimum Window Substring
58 Multiply Strings
59 N-Queens
60 N-Queens II
61 Next Permutation
62 Palindrome Number
63 Partition List
64 Pascal's Triangle
65 Pascal's Triangle II
66 Path Sum
67 Path Sum II
68 Permutation Sequence
69 Permutations
70 Permutations II
71 Plus One
72 Populating Next Right Pointers in Each Node
73 Populating Next Right Pointers in Each Node II
74 Pow(x, n)
75 Recover Binary Search Tree
76 Regular Expression Matching
77 Remove Duplicates from Sorted Array
78 Remove Duplicates from Sorted Array II
79 Remove Duplicates from Sorted List
80 Remove Duplicates from Sorted List II
81 Remove Element
82 Remove Nth Node From End of List
83 Restore IP Addresses
84 Reverse Integer
85 Reverse Linked List II
86 Reverse Nodes in k-Group
87 Roman to Integer
88 Rotate Image
89 Rotate List
90 Same Tree
91 Scramble String
92 Search a 2D Matrix
93 Search for a Range
94 Search in Rotated Sorted Array
95 Search in Rotated Sorted Array II
96 Search Insert Position
97 Set Matrix Zeroes
98 Simplify Path
99 Sort Colors
100 Spiral Matrix
101 Spiral Matrix II
102 Sqrt(x)
103 String to Integer (atoi)
104 Subsets
105 Subsets II
106 Substring with Concatenation of All Words
107 Sudoku Solver
108 Swap Nodes in Pairs
109 Symmetric Tree
110 Text Justification
111 Trapping Rain Water
112 Triangle
113 Two Sum
114 Unique Binary Search Trees
115 Unique Binary Search Trees II
116 Unique Paths
117 Unique Paths II
118 Valid Number
119 Validate if a given string is numeric.
120 Valid Parentheses
121 Valid Sudoku
122 Validate Binary Search Tree
123 Wildcard Matching
124 Word Search
125 ZigZag Conversion

leetcode Question 21: Construct Binary Tree from Preorder and Inorder Traversal

Construct Binary Tree from Preorder and Inorder Traversal

Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.

Analysis:

The idea is similar to the previous question. Just be careful with the order of dividing the vector, and the order of preorder root.

Code(C++):


/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int findId(int n, vector<int> &inorder){
        for (int i=0;i<inorder.size();i++){
            if (inorder[i] == n) return i;
        }
    }

    TreeNode* bst(vector<int> &preorder, int &mid, vector<int> &inorder, int st, int ed){
        if (st>ed || preorder.size()==mid){
            return NULL;
        }
        TreeNode* root = new TreeNode(preorder[mid]);
        int idx = findId(preorder[mid], inorder);
        mid++;
        root->left = bst(preorder, mid, inorder, st, idx-1);
        root->right = bst(preorder, mid, inorder, idx+1, ed);
        return root;
    }
    
    TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
        int mid = 0;
        return bst(preorder, mid, inorder, 0, inorder.size());
    }
};

Code(Python):

# Definition for a  binary tree node
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    # @param preorder, a list of integers
    # @param inorder, a list of integers
    # @return a tree node
    def bst(self, preorder, inorder):
        if len(preorder) == 0 or len(inorder) == 0:
            return None
        root = TreeNode(preorder[0])
        idx = inorder.index(preorder[0])
        preorder.pop(0)
        root.left = self.bst(preorder, inorder[0:idx]) 
        root.right = self.bst(preorder, inorder[idx+1:])
        return root
    
    
    def buildTree(self, preorder, inorder):
        return self.bst(preorder, inorder)
        

leetcode Question 20: Construct Binary Tree from Inorder and Postorder Traversal

Construct Binary Tree from Inorder and Postorder Traversal


Given inorder and postorder traversal of a tree, construct the binary tree.

Note:
You may assume that duplicates do not exist in the tree.

Analysis:

An easy solution is scan from the last element to the 1st element of the postorder vector. For each element, search the position in inorder vector, and place the element in a proper position of the tree. However, this method is time consuming, which cannot pass the large test.
Another idea is to use the recursion.
1. Find the last node in the postorder vector, which is the root of the current tree.
2. Find the position of root node in the inorder vector, which divide the inorder vector into 2 sub tree inorder vectors. Left part is the left sub-tree, right part is the right sub-tree.
3. Do 1 and 2 for the right and left sub-tree, respectively.
(Updated in 201309)
e.g. The tree is:
        1
   2        3
4   5         6
Inorder:         425136
Postorder:     452631

So, first we have 1 as the root node,  and find 1's position in inorder,   425   1    36
Then we search    inorder 36              as the right child,     and      inorder:    425    as the left child
                           postorder (452)63                                            postorder: 452


Code(C++):

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode *ct(vector<int> &inorder, vector<int> &postorder, int ist, int ied, int ped) {    
            if (ist>ied){return NULL;}
            TreeNode *res=new TreeNode(postorder[ped]);
            int mid;
            for (int i=ist;i<=ied;i++){
                if (inorder[i]==res->val){mid = i;break;}
            }
            res->right = ct(inorder,postorder,mid+1,ied,ped-1);
            res->left = ct(inorder,postorder,ist,mid-1, ped-1-ied+mid);
            return res;
    }


    TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (postorder.size()==0){
            return NULL;
        }else{
            return ct(inorder,postorder,0,inorder.size()-1,postorder.size()-1);
        }
            
    }    
};

Code(Python):


# Definition for a  binary tree node
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    # @param inorder, a list of integers
    # @param postorder, a list of integers
    # @return a tree node
    
    def newTree(self, ind, postd):
        if len(postd) == 0:
            return None
        root = TreeNode(postd[-1]) #get root node from postorder
        idx = ind.index(postd[-1]) #get root node index in inorder
        rlen = len(ind[idx+1:])  #length of the right subtree
        llen = len(ind) - rlen - 1 #length of the left subtree
        if rlen > 0:
            # get inorder right part and postorder last rlen elements
            root.right = self.newTree(ind[idx+1:], postd[-(rlen+1):-1])
        if llen > 0:
            # get inorder left part and postorder first llen elements
            root.left = self.newTree(ind[0:idx], postd[0:llen])
        return root
    
    def buildTree(self, inorder, postorder):
        return self.newTree(inorder, postorder)
        
        
        

leetcode Question 19: Combination

Combination


Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
For example,
If n = 4 and k = 2, a solution is:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

Analysis:

Standard DFS problem. Details see the code.




Source Code:


class Solution {
public:
    vector<vector<int> > res;
    
    
    
    void dfs(vector<int> &cand, int st, int ed, vector<int> &lr){
        if (lr.size()==ed){
            res.push_back(lr);
            return;
        }
        for (int i = st; i< cand.size();i++){
                lr.push_back(cand[i]);
                dfs(cand,i+1,ed,lr);
                lr.pop_back();
        }
        
        
    }
    vector<vector<int> > combine(int n, int k) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        res.clear();
        
        if ((k<1)||(n<1)||(k>n)){return res;}
        vector <int> cand;
        for (int i = 1; i<=n;i++){
            cand.push_back(i);
        }
        vector<int> lr;
        dfs(cand,0,k,lr);
        return res;
    }
};

leetcode Question 18: Combination Sum II

Combination Sum II



Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
Each number in C may only be used once in the combination.
Note:
  • All numbers (including target) will be positive integers.
  • Elements in a combination (a1a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
  • The solution set must not contain duplicate combinations.
For example, given candidate set 10,1,2,7,6,1,5 and target 8,
A solution set is:
[1, 7]
[1, 2, 5]
[2, 6]
[1, 1, 6] 

Analysis:

The only difference between this problem and the previous one is each element can be used at most once.
We can change the recursive step to handle this.

Code(C++):

class Solution {
public:
    void dfs(vector<int> &num, int target, vector<vector<int> > &res, vector<int> &r,int st){
        if (target<0){
            return;
        }else{
            if (target==0){
                res.push_back(r);
            }else{
                int pre = -1;
                for (int i=st;i<num.size();i++){
                    if (num[i]!=pre){
                        r.push_back(num[i]);
                        dfs(num,target-num[i],res,r,i+1);
                        pre = num[i];
                        r.pop_back();
                    }
                }
            }
        }
    }
    
    vector<vector<int> > combinationSum2(vector<int> &num, int target) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        vector<vector<int> > res;
        if (num.size()==0){return res;}
        sort(num.begin(),num.end());
        vector<int> r;
        dfs(num,target,res,r,0);
        return res;
    }
};

Code(Python):

class Solution:
    def search(self, candidates, target, i, res, ress):
        if target < 0:
            return
        else:
            if target == 0:
                res.append(ress[:]) #It is important to use "ress[:]" instead of "ress"
            else:
                for j in xrange(i, len(candidates)):
                    if j==0 or candidates[j] != candidates[j-1]:
                        ress.append(candidates[j])
                        self.search(candidates, target-candidates[j], j+1, res, ress)
                        ress.pop(-1) #if use "ress", this will pop the elemtnes in res also
    
    # @param {integer[]} candidates
    # @param {integer} target
    # @return {integer[][]}
    def combinationSum2(self, candidates, target):
        res =[]
        ress = []
        self.search(sorted(candidates), target, 0, res, ress)
        return res
        

leetcode Question 17: Combination Sum

Combination Sum



Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
  • All numbers (including target) will be positive integers.
  • Elements in a combination (a1a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
  • The solution set must not contain duplicate combinations.
For example, given candidate set 2,3,6,7 and target 7,
A solution set is:
[7]
[2, 2, 3] 

Analysis:


Because the problem is to get all the possible results, not the best or the number of result, thus we don't need to consider DP(dynamic programming), DFS is enough to handle it.

The idea is to scan from the first to the last element from the ordered array. (so first you need to sort the array) Then check every possible combination of numbers, note that each number can be used multiple times. So the looping in the function is not just from 0 to end, but for each element, keep use it until the sum is larger than the target.

All the possible selections of DFS are:
Each number in the array(multiple times can be used)

The termination condition of DFS is
1. the target ==0 , print list, return
2. the target < 0 return
3. start position >= array size return

Note: for python code, there is no "reference" (& in C++), when using the argument list, since "list" in python is mutable type, it can be considered as a reference in C++. But when you save the single result ("ress" in the code below), you have to use "ress[:]" to get the copy of each element in the variable, otherwise, when backtracking "ress", pop the last element in ress also pop the corresponding element in final result array "res".

Code(C++):

class Solution {
public:
    void dfs(vector<int> &candidates, int target, vector<vector<int> > &res, vector<int> &r, int i){
        if (target<0){
            return;
        }else{
            if (target==0){
                res.push_back(r);
            }else{
                while (i<candidates.size() && target-candidates[i]>=0){
                    r.push_back(candidates[i]);
                    dfs(candidates,target-candidates[i],res,r,i);
                    i++;
                    r.pop_back();
                }
            }
        }
        
    }
    vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        vector<vector<int> > res;
        if (candidates.size()==0){return res;}
        sort(candidates.begin(),candidates.end());
        vector<int> r;
        dfs(candidates,target,res,r,0);
        return res;
    }
};

Code(Python):

class Solution:
    def search(self, candidates, target, i, res, ress):
        if target < 0:
            return
        else:
            if target == 0:
                res.append(ress[:]) #It is important to use "ress[:]" instead of "ress"
            else:
                while i < len(candidates) and target-candidates[i] >= 0:
                    ress.append(candidates[i])
                    self.search(candidates, target-candidates[i], i, res, ress)
                    i += 1
                    ress.pop(-1) #if use "ress", this will pop the elemtnes in res also
    
    # @param {integer[]} candidates
    # @param {integer} target
    # @return {integer[][]}
    def combinationSum(self, candidates, target):
        res =[]
        ress = []
        self.search(sorted(candidates), target, 0, res, ress)
        return res
        

leetcode Question 16: Climbing Stairs


Climbing Stairs

You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

Analysis:


The easiest idea is a Fibonacci number. f(n) = f(n-1) + f(n-2). The nth stairs is from either n-1th the stair or the n-2th stair. However recursive is time-consuming. We know that recursion can be written in loop, the trick here is not construct a length of n array, only three element array is enough.

Updated(201407) Code (DP, Python):


class Solution:
    # @param n, an integer
    # @return an integer
    def climbStairs(self, n):
        f1=1;
        f2=2;
        if n<3:
            return n
        for i in xrange(3,n+1):
            f2 = f1+f2;
            f1 = f2-f1;
        return f2

Updated(201407) Code (DP,C++):

class Solution {
public:
    int climbStairs(int n) {
        if (n<3){return n;}
        int f1=1;
        int f2=2;
        for (int i=3;i<=n;i++){
            f2=f1+f2;
            f1=f2-f1;
        }
        return f2;
    }
};





The source code (recursively):
Note that this code is used for illustration, might not pass the online test.


class Solution {
public:
    int climbStairs(int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (n<=2) {return n;}
        else {
            return climbStairs(n-1) + climbStairs(n-2);
        }
    }
};



The source code (loop):

class Solution {
public:
    int climbStairs(int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int s[3]={0,1,2};
        if (n<=2) {return s[n];}
        int j = 2;
        while (true){
            j++;
            s[(j%3)] = s[((j+1)%3)] + s[((j+2)%3)];
            if (j==n) {return s[j%3];}
        }
    }
};

leetcode Question 15: Binary Tree Zigzag Level Order Traversal


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




Analysis:

The idea is much similar to the previous question "Binary Tree Level Order Traversal", the only difference is the print order for each level. Note that we store the level order while traverse the tree, otherwise the print could be a mass. Just consider the order when pushing the values into the result vector. deque is a good STL container which can deal with double-end push and pop operation.


It is more easier to modify the "two queue" version of level-order travsersal. Details can be seen in the Python code. 



Code(C++):


/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int> > zigzagLevelOrder(TreeNode *root) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        vector<vector<int> > res; //res vector
        if (root!=NULL){
            res.push_back(vector<int>(1,root->val)); // add root to the res
            deque<TreeNode*> q1,q2;
            vector<int> lev;
            q1.push_back(root);
            bool flag = false; //flag to decide the print order
            while (true){
                //level order traversal
                while (!q1.empty()){      
                    TreeNode* node = q1.front();
                    q1.pop_front();
                    if (node->left != NULL){q2.push_back(node->left);}
                    if (node->right != NULL){q2.push_back(node->right);}
                }
                if (q2.empty()){return res;}
                q1 = q2;
                //zigzag order print
                while (!q2.empty()){
                    if (flag){
                        lev.push_back(q2.front()->val);
                        q2.pop_front();
                    }else{
                        lev.push_back(q2.back()->val);
                        q2.pop_back();
                    }
                }
                res.push_back(lev);
                lev.clear();
                flag = !flag;
            }
        }
        
        return res;
        
    }
};

Code(Python):

# Definition for a  binary tree node
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    # @param root, a tree node
    # @return a list of lists of integers
    def zigzagLevelOrder(self, root):
        q1 = []
        q2 = []
        res = []
        if root == None:
            return res
        q1.append(root)
        l = []
        forward = True
        while True:
            while len(q1) !=0 :
                node = q1.pop(0)
                if node.left != None:
                    q2.append(node.left)
                if node.right != None:
                    q2.append(node.right)
                if forward == True:
                    l.append(node.val)    
                else:
                    l.insert(0, node.val)
            res.append(l)
            l = []
            q1 = q2
            q2 = []
            forward = not forward
            if len(q1) == 0:
                return res;