Friday, October 11, 2013

Day 47, #105, #106, #107, #114 Construct Binary Tree from Preorder and Inorder Traversal, Construct Binary Tree from Inorder and Postorder Traversal, Binary Tree Level Order Traversal II, Flatten Binary Tree to Linked List

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.
-----------------------------------------------
Explaination 
Having a start and an end pointer for each array.
Using hash table to track the root position in inorder array.
For preorder array, the first in partition is always the root node, for inorder one, in a given partition, all nodes whose indexes are less than root's are belong to its left child, whose indexes are greater than root's, belongs to its right child
Same algorithm for Postorder and Inorder combination

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void hashMapping(vector<int> &inorder, unordered_map<int,int>& mapping){
        for (int i = 0; i < inorder.size(); i++) {
            int k = inorder[i];
            mapping[k] = i;
        }
    }
    
    TreeNode *rec(vector<int> &preorder, vector<int> &inorder, int startP, int endP, int startI, int endI,unordered_map<int,int>& mapping) {
        //if (endI < startI || endP < startP)return NULL;
        int rootIndex = mapping[preorder[startP]];
        TreeNode *root = new TreeNode(preorder[startP]);
        // delimiter for preorder
        int delimiterIndex = rootIndex - startI + startP; 
        if (rootIndex > startI) {
            root->left = rec(preorder,inorder,startP+1,delimiterIndex,startI,rootIndex - 1,mapping);
        }else {
            root->left=NULL;
        }
        if (rootIndex < endI) {
            root->right = rec(preorder,inorder,delimiterIndex + 1,endP,rootIndex + 1,endI,mapping);
        }else {
            root->right=NULL;
        }
        return root;
    }
    
    TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
        // Note: The Solution object is instantiated only once and is reused by each test case.
        if (preorder.size() == 0) return NULL;
        unordered_map<int,int> mapping;
        hashMapping(inorder,mapping);
        return rec(preorder,inorder,0,preorder.size()-1,0,inorder.size()-1,mapping);
    }
};
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.
-----------------------------
Similar to Preorder and Inorder combination
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void hashMapping(vector<int> &inorder, unordered_map<int,int>& mapping){
        for (int i = 0; i < inorder.size(); i++) {
            int k = inorder[i];
            mapping[k] = i;
        }
    }

    TreeNode *rec(vector<int> &postorder, vector<int> &inorder, int startP, int endP, int startI, int endI,unordered_map<int,int>& mapping) {
        //if (endI < startI || endP < startP)return NULL;
        int rootIndex = mapping[postorder[endP]];
        TreeNode *root = new TreeNode(postorder[endP]);
        // delimiter for postorder
        int delimiterIndex = rootIndex - startI + startP-1; 
        if (rootIndex > startI) {
            root->left = rec(postorder,inorder,startP,delimiterIndex,startI,rootIndex - 1,mapping);
        }else {
            root->left=NULL;
        }
        if (rootIndex < endI) {
            root->right = rec(postorder,inorder,delimiterIndex + 1,endP-1,rootIndex + 1,endI,mapping);
        }else {
            root->right=NULL;
        }
        return root;
    }

    TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
        // Note: The Solution object is instantiated only once and is reused by each test case.
        if (postorder.size() == 0) return NULL;
        unordered_map<int,int> mapping;
        hashMapping(inorder,mapping);
        return rec(postorder,inorder,0,postorder.size()-1,0,inorder.size()-1,mapping);
    }
};
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],
] 
----------------------------------
Similar to #102 Binary Tree Level Order Traversal
This is a DFS solution 
 
/**
 * 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> > levelOrderBottom(TreeNode *root) {
    // Start typing your C/C++ solution below
    // DO NOT write int main() function
    vector<vector<int>> result;
    traverse(root, 1, result);
    std::reverse(result.begin(), result.end());
    return result;
}

void traverse(TreeNode *root, int level, vector<vector<int>> &result) {
    if (root == NULL) {
        return;
    }
    
    if (level > result.size()) {
        vector<int> v;
        result.push_back(v);
    }
    
    result[level-1].push_back(root->val);
    traverse(root->left,level+1,result);
    traverse(root->right,level+1,result);
}
};

Flatten Binary Tree to Linked List
Given a binary tree, flatten it to a linked list in-place.
For example,
Given
         1
        / \
       2   5
      / \   \
     3   4   6
The flattened tree should look like:
   1
    \
     2
      \
       3
        \
         4
          \
           5
            \
             6
----------------------------------------------------------
Solution #1, not in place, preorder traverse the tree, store each node in an array,

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void traverse (TreeNode *root, vector<TreeNode*>& v) {
        if (root != NULL) {
            v.push_back(root);
            traverse(root->left,v);
            traverse(root->right,v);
        }
    }

    void flatten(TreeNode *root) {
        // Note: The Solution object is instantiated only once and is reused by each test case.
        vector<TreeNode*> v;
        traverse(root,v);
        TreeNode *itr = root;
        for (int i = 1; i < v.size(); i++) {
            itr->right = v[i];
            itr->left = NULL;
            itr = itr->right;
        }
    }
};
Solution #2, in place iterative.
Same logic can be adopted in recursive implementation
O(n), 在inner loop里面,在整段代码的执行过程中每个node只出现过一次
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void flatten(TreeNode *root) {
        // Note: The Solution object is instantiated only once and is reused by each test case.
        TreeNode* ret = root;
        while (root != NULL) {
            if (root->left != NULL) {
                TreeNode *right = root->right;
                TreeNode *mostRight = root->left;
                
                while (mostRight->right != NULL) {
                    mostRight = mostRight->right;
                }
                mostRight->right = right;
                root->right = root->left;
                root->left = NULL;
            }
            root = root->right;
        }
        root = ret;
    }
};
Update on Sep-28-2014
Recursive solution, Pre-Order tree traversal
/**
 * 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* f(TreeNode *root, TreeNode *newRoot) {
        if (root == NULL) return newRoot;
        TreeNode *tempRight = root->right;
        newRoot->right = root;
        
        TreeNode *t = f(root->left,root); // return the end of list
        root->left = NULL;
        TreeNode *t2 = f(tempRight,t);
        return t2;
    }

    void flatten(TreeNode *root) {
        TreeNode *newRoot = root;
        TreeNode *dummy = new TreeNode(0);

        f(newRoot,dummy);
    }
};

Updated on Sep-24th-2018
跟上面类似思路,更易懂的写法。getEndOfList(root)返回以root为顶点的sub-tree转换成为list之后的最尾端的点
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {

    public void flatten(TreeNode root) {
        if (root == null) return;
        getEndOfList(root);
    }
    
    private TreeNode getEndOfList(TreeNode root) {

        TreeNode l = root.left;
        TreeNode r = root.right;
        if (root.left != null) {
            TreeNode end = getEndOfList(root.left);
            root.right = l;
            l = end;
            end.right = r;
            root.left = null;
        }
        
        if (r != null) {
            return getEndOfList(r);
        }
        if (l == null) {
            return root;
        }
        return l;   
    }
}

Wednesday, October 9, 2013

Day 46, ##, #102 Copy List with Random Pointer, Binary Tree Level Order Traversal

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.
------------------------------------------
The key point here is to set a direct link between the original node and its duplicate. So during the second iteration, the new/duplicate *next and *random nodes can be traced by their original nodes.

Besides using a map, the link can be implemented by attaching each duplicate right after to its original node in the linked list.

/**
 * Definition for singly-linked list with a random pointer.
 * struct RandomListNode {
 *     int label;
 *     RandomListNode *next, *random;
 *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
 * };
 */
class Solution {
public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        // Note: The Solution object is instantiated only once and is reused by each test case.
        if (head == NULL) return NULL;
        RandomListNode *ret = head, *itr = head;
        unordered_map<RandomListNode*,RandomListNode*> mapping;
        // set up the relationship between orignial and its duplicates
        while (itr != NULL) {
            RandomListNode *dup = new RandomListNode(itr->label);
            mapping[itr] = dup;
            itr = itr->next;
        }
        itr = head;
        // second iteration, set up *next and *random for duplicates
        while (itr != NULL) {
            RandomListNode *dup = mapping[itr];
            dup->next = mapping[itr->next];
            dup->random = mapping[itr->random];
            itr= itr->next;
        }
        return mapping[head];
    }
};

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 iterativ
Typical breadth first search, keep two queues to track all the nodes, use an integer to determine which should be used for current iteration
Challenge: use DFS to solve this 
check #107 Binary Tree Level Order Traversal II for DFS recursive solution
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void foo (queue<TreeNode*>& cur, queue<TreeNode*>& next, vector<int>& level) {
        while (!cur.empty()) {
            TreeNode* current = cur.front();
            cur.pop();
            level.push_back(current->val);
            if (current->left != NULL) {
                next.push(current->left);
            }
            if (current->right != NULL) {
                next.push(current->right);
            }
        }
    }

    vector<vector<int> > levelOrder(TreeNode *root) {
        // Note: The Solution object is instantiated only once and is reused by each test case.
        queue<TreeNode*> que,p;
        vector<vector<int> > ret;
        if (root == NULL) return ret;
        int levelCount = 0;
        que.push(root);
        while (!que.empty() || !p.empty()) {
            vector<int> level;
            if (levelCount % 2 == 0) {
                foo(que,p,level);
            }else {
                foo(p,que,level);
            }
            ret.push_back(level);
            levelCount++;
        }
        return ret;
    }
};
Update on Sep-24-2014 
refactoried
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void traverse(vector<vector<int> > &rt, queue<TreeNode*> &q1, queue<TreeNode*> &q2) {
        vector<int> v;
        while (!q1.empty()) {
            TreeNode * top = q1.front();
            q1.pop();
            v.push_back(top->val);
            if (top->left != NULL) q2.push(top->left);
            if (top->right != NULL) q2.push(top->right);
            
        }
        
        rt.push_back(v);
    }

    vector<vector<int> > levelOrder(TreeNode *root) {
        vector<vector<int> > rt;
        if (root == NULL) return rt;
        queue<TreeNode*> q1;
        queue<TreeNode*> q2;
        q1.push(root);
        
        while (!q1.empty() || !q2.empty()) {
            if (!q1.empty()) {
                traverse(rt,q1,q2);
            }
            if (!q2.empty()) {
                traverse(rt,q2,q1);
            }
        }
        
        return rt;
    }
};
Update on Sep-26-2014 
DFS
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void dfs(vector<vector<int> > &rt, int level, TreeNode *root) {
        if (root == NULL) return;
        
        if (rt.size() < level) {
            vector<int> v;
            rt.push_back(v);
        }
        
        rt[level - 1].push_back(root->val);
        dfs(rt,level + 1, root->left);
        dfs(rt,level + 1, root->right);
        
    }

    vector<vector<int> > levelOrder(TreeNode *root) {
        vector<vector<int> > rt;
        dfs(rt,1,root);
        return rt;
    }
};
Java, updated on Jul-30th-2018
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> rt = new ArrayList<>();
        if (root == null) return rt;
        
        Queue<TreeNode> que = new LinkedList<>();
        que.add(root);
        int size = 1;
        rt.add(new ArrayList<>());
        
        while (!que.isEmpty()) {
            if (size == 0) {
                rt.add(new ArrayList<>());
                size = que.size();
            }
            
            size--;
            TreeNode node = que.poll();
            rt.get(rt.size() - 1).add(node.val); 
            if (node.left != null) que.add(node.left);
            if (node.right != null) que.add(node.right);
        }
        
        return rt;
    }
}

Thursday, September 19, 2013

Day 45, #98 Validate Binary Search Tree

Validate Binary Search Tree
Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
  • The left subtree of a node contains only nodes with keys less than the node's key.
  • The right subtree of a node contains only nodes with keys greater than the node's key.
  • Both the left and right subtrees must also be binary search trees.
---------------------------------------------------
Perform an in-order tree traversal, save all values in an array, and later check if it is sorted
There is room for space optimization in solution below
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void rec (TreeNode *root, vector<int> &v) {
        if (root->left != NULL) {
            rec(root->left,v);
        }
        v.push_back(root->val);
        if (root->right != NULL) {
            rec(root->right,v);
        }
    }

    bool isValidBST(TreeNode *root) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (root == NULL) return true; 
        vector<int> v;
        rec(root,v);
        if (v.size() < 2) {
            return true;
        }
        // check if it's already sorted
        for (int i = 1; i < v.size(); i++) {
            if (v[i-1] >= v[i]) {
                return false;
            }
        }
        return true;
    }
};
Update: Jan-16-2014
http://leetcode.com/2010/09/determine-if-binary-tree-is-binary.html
Solution#2, in space.
Note int &pre in arguments
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool inorder (TreeNode *root, int &pre) {
       if (root == NULL) {
           return true;
       }
       if (inorder(root->left,pre)) {
           if (pre >= root->val) {
               return false;
           }
           pre = root->val;
           return inorder(root->right,pre);
       }
       return false;
       
    }

    bool isValidBST(TreeNode *root) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (root == NULL) return true; 
        int pre = INT_MIN;
        return inorder(root,pre);
    }
};

Update: Jan-15-2015
to handle INT_MIN case
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool inorder(TreeNode *root, TreeNode *&pre) {
        if (root == NULL) {
            return true;
        }
        
        if (inorder(root->left,pre)) {
            if (pre != NULL && pre->val >= root->val) {
                return false;
            }
            pre = root;
            return inorder(root->right,pre);
            
        }
        
        return false;
    }

    bool isValidBST(TreeNode *root) {
        TreeNode *pre = NULL;
        return inorder(root,pre);
    }
};

Java, updated Jun-24th-2018
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    
    private TreeNode pre = null;
    public boolean isValidBST(TreeNode root) {
        if (root == null) return true;
        if (!isValidBST(root.left)) {
            return false;
        }
        
        if (pre == null) pre = root;
        else if (pre.val >= root.val) {
            return false;
        }
        pre = root;
        return isValidBST(root.right);
    }
}

当有node的值等于MIN_VALUE或MAX_VALUE, 这算法就搞不定了。所有还是别用了
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isValidBST(TreeNode root) {
        return helper(root, Integer.MIN_VALUE, Integer.MAX_VALUE);
    }
    
    private boolean helper(TreeNode root, int min, int max) {
        if (root == null) return true;
        if (root.val < max && root.val > min) {
            return helper(root.left, min, root.val) 
                && helper(root.right, root.val, max);
        }
        
        return false;
    }
}

Wednesday, September 11, 2013

Day 44, #96 Unique Binary Search Trees

Unique Binary Search Trees
Given n, how many structurally unique BST's (binary search trees) that store values 1...n?
For example,
Given n = 3, there are a total of 5 unique BST's.
   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3 
-------------------------------------------------
Catalan Number 
COME_BACK


class Solution {
public:
    int numTrees(int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        int ret = 1;
        for (int i = 2; i <= n; i++) {
            ret = 2*(2*i-1)*ret/(i+1);
        }
        return ret;
    }
};
DP
class Solution {
public:
    int numTrees(int n) {
        vector<int> dp(n + 1,0);
        dp[0] = dp[1] = 1;
        for (int i = 2; i <= n; i++) {
            for (int j = 0; j < i; j++) {
                dp[i] += dp[j] * dp[i - j - 1];
            }
        }
        return dp[n];
    }
};

Thursday, September 5, 2013

Day 43, #93 Restore IP Addresses

Restore IP Addresses
Given a string containing only digits, restore it by returning all possible valid IP address combinations.
For example:
Given "25525511135",
return ["255.255.11.135", "255.255.111.35"]. (Order does not matter)
----------------------------------------------------
DFS

class Solution {
public:
    int stringToInt (string s) {
        int num = 0;
        for (int i = 0; i < s.length(); i++) {
            num = num * 10;
            int temp  = s[i] - '0';
            num = num + temp;
        }
        return num;
    }

    void rec (string cur, string s, int count, vector<string> &ret) {
        if (s.length() == 0 && count == 4) {
            ret.push_back(cur);
        }else if (count < 4 && s.length() != 0) {
            if (count != 0) { // no '.' before the first part 
                cur = cur + ".";
            }
            string temp;
            if (s.length() >= 1) {
                temp = cur + s[0];
            rec(temp,s.substr(1),count+1,ret);
            }
            if (s.length() >= 2 && s[0] != '0') {
                temp = cur + s.substr(0,2);
            rec(temp,s.substr(2),count+1,ret);
            }
            if (s.length() >= 3 && s[0] != '0') {
                temp = cur + s.substr(0,3);
                if (stringToInt(s.substr(0,3)) < 256) {
                    rec(temp,s.substr(3),count+1,ret);
                }
            }
        }
        
    }

    vector<string> restoreIpAddresses(string s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        vector<string> ret;
        rec("",s,0,ret);
        return ret;
        
    }
};
Update on Sep-21-2014 
Same algorithm but with index
class Solution {
public:
    void rec(vector<string> &rt, string s, int index, int count,string ip) {
        if (count == 4 && index == s.length()) {
            rt.push_back(ip);
            return;
        }
        
        if (count > 4 || index > s.length()) return;
        
        if (count != 0) {
            ip += "."; 
        }
        
        rec(rt,s,index + 1, count + 1, ip + s.substr(index,1));
        
        if (index + 1 < s.length() && s[index] != '0') {
            string sub = s.substr(index,2);
            rec(rt,s,index + 2, count + 1, ip + sub);
        }
        
        if (index + 2 < s.length() && s[index] != '0') {
            string sub = s.substr(index,3);
            if (stoi(sub) < 256) {
                rec(rt,s,index + 3, count + 1, ip + sub);
            }
        }
        
    }

    vector<string> restoreIpAddresses(string s) {
        vector<string> rt;
        if (s == "") return rt;
        rec(rt,s,0,0,"");
        
        return rt;
    }
};

Wednesday, August 28, 2013

Day 42, #92, #109, Reverse Linked List II, Convert Sorted List to Binary Search Tree

Reverse Linked List II
Reverse a linked list from position m to n. Do it in-place and in one-pass.
For example:
Given 1->2->3->4->5->NULL, m = 2 and n = 4,
return 1->4->3->2->5->NULL.
Note:
Given m, n satisfy the following condition:
1 ? m ? n ? length of list.
----------------------------------------
lets say m = 3, n = 5
1             2              3             4             5            6
|              |                |                             |
head      left           tail                     newHead

/* Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *reverseBetween(ListNode *head, int m, int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        ListNode *newHead = NULL, *itr = head,*left = NULL,*tail;
        // move to m-th node
        for (int i = 1; i < m; i++) {
            left = itr;
            itr = itr->next;
        }
        tail = itr;
        // move to n-th node
        for (int i = m; i <= n; i++) {
            ListNode *temp = itr->next;
            itr->next = newHead;
            newHead = itr;
            itr = temp;
        }
        tail->next = itr;
        if (m == 1) {
            return newHead;
        }
        left->next = newHead;
        return head;
    }
};
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.
--------------------------------------------------------------------------
Further reading:
http://leetcode.com/2010/11/convert-sorted-list-to-balanced-binary.html
http://www.geeksforgeeks.org/sorted-linked-list-to-balanced-bst/
/**
 * 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* constructTree (ListNode *&list,int start, int end) {
        if (start > end) {
            return NULL;
        }
        int mid = start + (end - start) / 2;
        TreeNode *left = constructTree(list,start,mid - 1);
        TreeNode *root = new TreeNode(list->val);
        root->left = left;
        list = list->next;
        root->right = constructTree(list,mid + 1, end);
        return root;
    }


    TreeNode *sortedListToBST(ListNode *head) {
        int n = 0;
        ListNode *itr = head;
        while (itr != NULL ) {
            n++;
            itr = itr->next;
        }
        return constructTree(head,0,n-1);
    }
};
Update Nov-21-2014
Bottom up solution. For each node, build the left child -> root -> right child, follow the in order sequence

Monday, August 26, 2013

Day 41, 91 Decode Ways

Decode Ways
A message containing letters from A-Z is being encoded to numbers using the following mapping:
'A' -> 1
'B' -> 2
...
'Z' -> 26
Given an encoded message containing digits, determine the total number of ways to decode it.
For example,
Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12).
The number of ways decoding "12" is 2.
------------------------------------------------
similar to steps problem, with some extra conditions
Solution #1 simple recursion
class Solution {
public:
    int numDecodings(string s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (s.length() == 0 || s[0] == '0') return 0;
        if (s.length() == 1) return 1;
        int fix = 0;
        if (s.length() == 2) {
            fix = 1;
        }
        if (s[0] == '1' || (s[0] == '2' && s[1] < '7')) {
            return numDecodings(s.substr(1)) + numDecodings(s.substr(2)) + fix;
        }
        return numDecodings(s.substr(1));
    }
};
Solution #2 DP
class Solution {
public:
    int numDecodings(string s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (s.length() == 0 || s[0] == '0') {
            return 0;
        }
        vector<int> ways(s.length() + 1, 1);
        for (int i = s.length() - 1; i >= 0; i--) {
            if (s[i] == '0') {
                ways[i] = 0;
            }else {
                ways[i] = ways[i+1];
            }
            if (i+1 < s.length() && (s[i] == '1' || (s[i] == '2' && s[i+1] < '7'))) {
                ways[i] += ways[i+2];
            }
        }
        return ways[0];
    }
};

In Java, recursion with memoization
class Solution {
    private Map<String, Integer> map = new HashMap<>();
    public int numDecodings(String s) {
        if (s.length() == 0 || s.charAt(0) == '0') return 0;
        if (s.length() == 1) {
            return 1;
        }
        
        int i = 0;
        String s1 = s.substring(1);
        if (map.containsKey(s1)) {
            i = map.get(s1);
        }else {
            i = numDecodings(s.substring(1)); 
            map.put(s.substring(1), i);
        }
        
        if (s.charAt(0) == '1' || (s.charAt(0) == '2' && s.charAt(1) < '7')) {
            
            String s2 = s.substring(2);
            int j = 0;
            
            if (map.containsKey(s2)) {
                j = map.get(s2);
            }else {
                j = numDecodings(s2); 
                map.put(s2, j);
            }
            
            int rt = 0;
            if (s.length() == 2) rt = 1;
            return i + j + rt;
        }
        
        return i;
    }
}

COME_BACK
写一下O(1) 空间复杂度