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;
    }
};