Tuesday, July 15, 2014

valid BST -- Leetcode

From Geeksforgeeks:

METHOD 2 (Correct but not efficient)
For each node, check if max value in left subtree is smaller than the node and min value in right subtree greater than the node.
/* Returns true if a binary tree is a binary search tree */
int isBST(struct node* node)
{
  if (node == NULL)
    return(true);
     
  /* false if the max of the left is > than us */
  if (node->left!=NULL && maxValue(node->left) > node->data)
    return(false);
     
  /* false if the min of the right is <= than us */
  if (node->right!=NULL && minValue(node->right) < node->data)
    return(false);
   
  /* false if, recursively, the left or right is not a BST */
  if (!isBST(node->left) || !isBST(node->right))
    return(false);
     
  /* passing all that, it's a BST */
  return(true);
}
It is assumed that you have helper functions minValue() and maxValue() that return the min or max int value from a non-empty tree


METHOD 3 (Correct and Efficient)
Method 2 above runs slowly since it traverses over some parts of the tree many times. A better solution looks at each node only once. The trick is to write a utility helper function isBSTUtil(struct node* node, int min, int max) that traverses down the tree keeping track of the narrowing min and max allowed values as it goes, looking at each node only once. The initial values for min and max should be INT_MIN and INT_MAX — they narrow from there.
/* Returns true if the given tree is a binary search tree 
 (efficient version). */ 
int isBST(struct node* node) 
{ 
  return(isBSTUtil(node, INT_MIN, INT_MAX)); 
} 

/* Returns true if the given tree is a BST and its 
 values are >= min and <= max. */ 
int isBSTUtil(struct node* node, int min, int max) 
Implementation:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
 
/* A binary tree node has data, pointer to left child
   and a pointer to right child */
struct node
{
    int data;
    struct node* left;
    struct node* right;
};
 
int isBSTUtil(struct node* node, int min, int max);
 
/* Returns true if the given tree is a binary search tree
 (efficient version). */
int isBST(struct node* node)
{
  return(isBSTUtil(node, INT_MIN, INT_MAX));
}
 
/* Returns true if the given tree is a BST and its
   values are >= min and <= max. */
int isBSTUtil(struct node* node, int min, int max)
{
 
  /* an empty tree is BST */
  if (node==NULL)
     return 1;
       
  /* false if this node violates the min/max constraint */ 
  if (node->data < min || node->data > max)
     return 0;
 
  /* otherwise check the subtrees recursively,
   tightening the min or max constraint */
  return
    isBSTUtil(node->left, min, node->data-1) &&  // Allow only distinct values
    isBSTUtil(node->right, node->data+1, max);  // Allow only distinct values
}
 
Time Complexity: O(n)
Auxiliary Space : O(1) if Function Call Stack size is not considered, otherwise O(n)

METHOD 4(Using In-Order Traversal)
Thanks to LJW489 for suggesting this method.
1) Do In-Order Traversal of the given tree and store the result in a temp array.
3) Check if the temp array is sorted in ascending order, if it is, then the tree is BST.
Time Complexity: O(n)
We can avoid the use of Auxiliary Array. While doing In-Order traversal, we can keep track of previously visited node. If the value of the currently visited node is less than the previous value, then tree is not BST. Thanks to ygos for this space optimization.
bool isBST(struct node* root)
{
    static struct node *prev = NULL;
     
    // traverse the tree in inorder fashion and keep track of prev node
    if (root)
    {
        if (!isBST(root->left))
          return false;
 
        // Allows only distinct valued nodes
        if (prev != NULL && root->data <= prev->data)
          return false;
 
        prev = root;
 
        return isBST(root->right);
    }
 
    return true;
}
The use of static variable can also be avoided by using reference to prev node as a parameter (Similar to this post).


letter combination of mapping dictionary 1 -- FB

/*
Given a hashmap M which is a mapping of characters to arrays of substitute characters, and an input string S, return an array of all possible mutations of S (where any character in S can be substituted with one of its substitutes in M, if it exists).

What is the time complexity? What is the space complexity? Can you optimize either?

Example input:
M = { f: [F, 4], b: [B, 8] }
S = fab

Expected output:
[fab, Fab, 4ab, faB, FaB, 4aB, fa8, Fa8, 4a8]
*/
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <string>
#include <unordered_map>
#include <iostream>

using namespace std;

void permuteHelp(unordered_map<char,vector<char>> &mmap, string &s, int level, string &seq, vector<string> &res){
if(level == s.size()){
res.push_back(seq);
   return;
}

char c= s[level];
if(mmap.count(c)){
seq.append(1,c);          //add itself.
   permuteHelp(mmap,s,level+1,seq,res);
seq.resize(seq.size()-1);

        for(int i=0;i<mmap[c].size();++i){
seq.append(1,mmap[c][i]);
permuteHelp(mmap,s,level+1,seq,res);
seq.resize(seq.size()-1);            //backtrack!!!
}
}
else{
seq.append(1,c);
   permuteHelp(mmap,s,level+1,seq,res);
seq.resize(seq.size()-1);
}
return;
}

vector<string> lettercombi(unordered_map<char,vector<char>> &mmap, string s){
vector<string> res;
string seq;
permuteHelp(mmap, s, 0, seq, res);
return res;
}

int main(){
unordered_map<char,vector<char>> mmap;
vector<string> res;

char a[] = {'F','4'};
vector<char> veca(a,a+2);
mmap.insert(make_pair('f',veca));
char b[] = {'B','8'};
vector<char> vecb(b,b+2);
mmap.insert(make_pair('b',vecb));

res = lettercombi(mmap,"fab");
for(int i=0;i<res.size();++i){
cout<< res[i]<<endl;
}
getchar();
return 0;
}

Check is BT is balanced -- Leetcode

Question:

Answer:
1. My code :
  /**
 * 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 isBalanced(TreeNode *root) {
       if (!root) return true;
     
   else if(!isBalanced(root->left) || !isBalanced(root->right)) return false;

   int height1 = height(root -> left);
   int height2 = height(root -> right);
   if (abs(height1-height2) <= 1) return true;
   else return false;
}
 
int height(TreeNode *root){
    if(!root) return 0;
    else return max(height(root->left),height(root->right)) + 1;
}
};

2.Code online:
/******Better!*******/
class Solution {
public:
    bool isBalanced(TreeNode *root) {    
      if(root == NULL) return true;
      int val = GetBalance(root);
      if(val ==-1) return false;
      return true;        
       
    }  
    int GetBalance(TreeNode* node) {
      if(node == NULL)
        return 0;
      int left = GetBalance(node->left);
      if(left == -1) return -1;
      int right = GetBalance(node->right);
      if(right == -1) return -1;
      if(left-right>1 || right-left>1)
        return -1;
      return left>right? left+1:right+1;
    }  
};

Monday, July 14, 2014

Letter combination of a phone number -- Leetcode

Question:
Given a digit string, return all possible letter combinations that the number could represent.
A mapping of digit to letters (just like on the telephone buttons) is given below.
Input:Digit string "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
Answer:
C++ version:
class Solution {
public:
    vector<string> letterCombinations(string digits) {
        string mmap[] = {"", " ", "abc", "def", "ghi", "jkl",
        "mno", "pqrs", "tuv", "wxyz"};
        vector<string> res;    
        string seq;
        Generater(mmap, digits, 0, seq, res);
        return res;
   }
   void Generater(string mmap[], string& digits, int level, string& subres, vector<string>& res){
       if(level == digits.size()){
           res.push_back(subres);
           return;
       }
       int digint = digits[level] - '0';
       for(int i =0; i < mmap[digint].size(); i++){
           subres.push_back(mmap[digint][i]);
           Generater(mmap, digits, level+1, subres,res);
           subres.resize(subres.size() -1);
      }
   }
};



Java version:
public class Solution {
   
    public List<String> letterCombinations(String digits) {
        String[] mmap = {""," ","abc","def","ghi","jkl", "mno", "pqrs", "tuv", "wxyz"};
        List<String> res = new ArrayList<String>();
        String subres = new String();
        generate(mmap, digits, 0, subres, res);
        return res;
    }
   
    public void generate(String[] mmap, String digits, int idx, String subres, List<String> res){
        if(idx == digits.length()){
            res.add(subres);
            return;
        }
       
        int digit = digits.charAt(idx) - '0';
        for(int i=0; i<mmap[digit].length();++i){
            subres += mmap[digit].charAt(i);
            generate(mmap, digits, idx+1, subres, res);
            subres = subres.substring(0,subres.length()-1);
        }
        return;
    }
}