Tuesday, February 11, 2014

[leetcode][***] Longest Consecutive Sequence


Given an unsorted array of integers, find the length of the longest consecutive elements sequence.
For example,
Given [100, 4, 200, 1, 3, 2],
The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4.
Your algorithm should run in O(n) complexity.
Algorithm:
1. unordered_set is needed to be the hashtable.
2. for each one check the whole consecutive sequence containing it. and on each check delete the checked ones.

My Code:
int longestConsecutive(vector<int> num) {
        // use unordered_set to insert and find for constant.
        unordered_set<int> numset;
        for(int i = 0; i < num.size(); ++i)
            numset.insert(num[i]);
        int len = 1;
        for(int i = 0; i < num.size(); ++i){
            int u = num[i];
            int v = u;
            int count = 1;
            if(numset.find(v)!=numset.end()){
                numset.erase(v);
                while(numset.find(--v)!=numset.end()){
                    numset.erase(v);
                    ++count;
                }
                v = u;
                while(numset.find(++v)!=numset.end()){
                    numset.erase(v);
                    ++count;
                }
                if(count < len){
                    len = count;
                }
            }
            
        }
        return len;
    }

Saturday, February 8, 2014

[leetcode][***] Unique Tree


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
This is a DP problem.
In Order, n = 0, result = 1:

int numTrees(int n) {
      int table[n+1];
      memset(table, 0, sizeof(int)*(n+1));
      for(int i = 0; i <= n; ++i){
          if(i < 2) table[i] = 1;
          else{
              for(int j = 0; j < i; ++j){
                  table[i] += table[j]*table[i-j-1];
              }
          }
      }
      return table[n];
    }

[leetcode][***] 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.

C++ wont initialize automatically for you!!!

Idea:
1. Inorder traversal and see if it is in the increasing order.
First Code(Run Time Error at first):The problem is that I should initialize the pre pointer to NULL!

bool isValidBST(TreeNode *root) {
        if(!root) return true;
        stack<TreeNode*> s;
        TreeNode* temp = root;
        TreeNode* pre = NULL;
        TreeNode* cur;
        while(temp){
            s.push(temp);
            temp = temp->left;
        }
        while(!s.empty()){
            cur = s.top();
            if(pre)
                if(pre->val >= cur->val) return false;
            pre = cur;
            s.pop();
            if(cur->right){
                cur = cur->right;
                while(cur){
                    s.push(cur);
                    cur = cur->left;
                }
            }
        }
        return true;
    }

Friday, February 7, 2014

[leetcode][****] LRU Cache

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.

Key Idea:

1. Here we need a queue to dequeue the least recently item. However as we need the randomly access of the items for set and get, queue in C++ STL will not meet the standard. Then, we need a doubly linked list to build the queue.

2. In the doubly linked list, we should have key, value, pre, and nxt in the list node.

3. In order to find the node via the key each time fast, we need a hashmap, in C++, we could use

map<int, QNode*>.

4. When get(key) called, the position of the node if existed should moved to the last as well.

5. When set(key, val) called, if existed, then change value and move to the last, pay attention for one node list and if current is on front or rear node; if not existed, check if full or not, if full, dequeue; then insert to the last node.

SHOULD ALWAYS PAY ATTENTION TO THE SPECIAL CASES: only one node, current is front or last.
struct QNode{
    int key;
    int value;
    QNode* pre;
    QNode* nxt;
    QNode(int k, int val){key = k; value = val;}
};
struct Queue{
    // current count of contents.
    int count;    
    // total capacity
    int numofnode;
    QNode* front;
    QNode* rear;
    Queue(int n){
        count = 0;
        numofnode = n;
        front = rear = NULL;
    }
    bool IsQueueFull(){
        return count == numofnode;
    }
    bool IsQueueEmpty(){
        return rear == NULL;
    }
    void Dequeue(){
        if(IsQueueEmpty()) return;
        //if only one node in the queue
        if(front == rear){
            delete front;
            front = NULL;
            rear = NULL;
            count = 0;
            return;
        }
        QNode* temp = front;
        front = temp->nxt;
        front->pre = NULL;
        delete temp;
        --count;
    }
    void Enqueue(QNode* node){
        if(IsQueueFull())
            Dequeue();
        if(IsQueueEmpty()){
            node->nxt = NULL;
            node->pre = NULL;
            front = node;
            rear = node;
            count = 1;
            return;
        }
        rear->nxt = node;
        node->pre = rear;
        node->nxt = NULL;
        rear = node;
        ++count;
    }
};

class LRUCache{
public:
    
    LRUCache(int capacity) {
        LRUqueue = new Queue(capacity);
    }
    
    int get(int key) {
        QNode* cur = LRUmp[key];
        //if current key is not in the map
        if(!cur) return -1;
        else{
            if(LRUqueue->front != LRUqueue->rear){
                if(cur == LRUqueue->rear){
                    return cur->value;
                }
                if(cur == LRUqueue->front){
                    LRUqueue->front = cur->nxt;
                }else{
                    cur->pre->nxt = cur->nxt;
                    cur->nxt->pre = cur->pre;
                }
                LRUqueue->rear->nxt = cur;
                cur->pre = LRUqueue->rear;
                cur->nxt = NULL;
                LRUqueue->rear = cur;
            }
            return cur->value;
        }
    }
    
    void set(int key, int value) {
        QNode* cur = LRUmp[key];
        // if not in the map, we need to insert to the queue and the map.
        if(!cur){
            cur = new QNode(key, value);
            //check if the queue is full
            if(LRUqueue->IsQueueFull()){
                LRUmp.erase(LRUqueue->front->key);
                //enqueue the current value.
                LRUqueue->Enqueue(cur);
                LRUmp[key] = cur;
            }else{
                LRUqueue->Enqueue(cur);
                LRUmp[key] = cur;
            }
        }else{
            // if the key->node is in the map and queue
            if(LRUqueue->front != LRUqueue->rear){
                if(cur == LRUqueue->rear){
                    cur->value = value;
                    LRUmp[key] = cur;
                    return;
                }
                if(cur == LRUqueue->front){
                    LRUqueue->front = cur->nxt;
                }else{
                    cur->pre->nxt = cur->nxt;
                    cur->nxt->pre = cur->pre;
                }
                LRUqueue->rear->nxt = cur;
                cur->pre = LRUqueue->rear;
                cur->nxt = NULL;
                LRUqueue->rear = cur;
            }
            cur->value = value;
            LRUmp[key] = cur;
        }
        
    }
private:
    Queue* LRUqueue;
    map<int, QNode*> LRUmp;
};

Thursday, February 6, 2014

[leetcode][****] Single Number II


Given an array of integers, every element appears three times except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
Algorithm:
This problem is very hard actually. The train of thought is that, %3. 
1) For every bit of each number, we should make the count of 1 mode 3. If repeated n times, then mode n.
2) As the result of %3 can be 0,1,2. Then the result should be kept in two bits instead of one. 
3) should think about for all one bit numbers as {a1, a2, ...., a3}. how to calculate 
    (a1 + a2 + a3+ ...+ an)%3 with bit operation. (&, |, ^). This is also hard to see. Then check the easier 
    problem of (a+b)%3. The truth table shoule be:
    a    b     results
    0   0      0    0
    0   1      0    1
    1   0      0    1
    1   1      1    0


[CareerCup] Given a node of Binary Tree.

[leetcode][**] Minimum Depth of Binary Tree

Given a binary tree, find its minimum depth.
The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.
Attention: 
from root to leaf distance 
               1
        2
   3        5
4
this distance is till 3 not 1. should find the nearest leaf!!
My Code:
int minDepth(TreeNode *root) {
        if(root == NULL) return 0;
        else if(root->left == NULL && root->right == NULL)
            return 1;
        else if(root->left == NULL && root->right != NULL)
            return 1 + minDepth(root->right);
        else if(root->right == NULL && root->left != NULL)
            return 1 + minDepth(root->left);
        else
            return 1 + std::min(minDepth(root->left), minDepth(root->right));
        }