Wednesday, October 29, 2014

Notes for Leetcode's blog

Sliding window(已看,已理解,未写)
http://leetcode.com/2011/01/sliding-window-maximum.html

方法1:暴力解
方法2:for 循环内每一步计算的都是上一步的window的最大值,所以最后一个window得单独计算
注意: priority_queue每次push或者pop都会重新生成最大/小值在开头
方法3:用双向链表,queue里存的是element的index。当前的最大值永远在最前,不用考虑比最大值小的值。每当插入一个新的值,pop掉所有比它小的值。之后在对比当前最大值是否在范围(window)内

Sunday, October 12, 2014

Notes on Notes -- Chapter 2, 3, 4*

chapter 2
设定dummy

----------

chapter 3
Tower of Hanoi
iterative solution
http://en.wikipedia.org/wiki/Tower_of_Hanoi
--------

chapter4

trie -- implementation
http://en.wikipedia.org/wiki/Trie

heap

priority queue

graph -- implementation
http://www.cs.bu.edu/teaching/c/graph/linked/



Dijkstra's algorithm

greedy

Check if a graph has a cycle
undirected: use DFS
directed: use Topological sorting

lowest common ancestor
http://leetcode.com/2011/07/lowest-common-ancestor-of-a-binary-tree-part-i.html

Find the immediate right neighbor of the given node, with parent links given, but without root node.( Ebay interview question)

Word Ladder II 

Saturday, June 28, 2014

Notes: Distributed System -- Chubby, Zookeeper

Use of Chubby or Zookeeper
  • Group membership and name services
    By having each node register an ephemeral znode for itself (and any roles it might be fulfilling), you can use ZooKeeper as a replacement for DNS within your cluster. Nodes that go down are automatically removed from the list, and your cluster always has an up-to-date directory of the active nodes.
  • Distributed mutexes and master election
    We discussed these potential uses for ZooKeeper above in connection with sequential nodes. These features can help you implement automatic fail-over within your cluster, coordinate concurrent access to resources, and make other decisions in your cluster safely.
  • Asynchronous message passing and event broadcasting
    Although other tools are better suited to message passing when throughput is the main concern, I’ve found ZooKeeper to be quite useful for building a simple pub/sub system when needed. In one case, a cluster needed a long sequence of actions to be performed in the hours after a node was added or removed in the cluster. On demand, the sequence of actions was loaded into ZooKeeper as a group of sequential nodes, forming a queue. The “master” node processed each action at the designated time and in the correct order. The process took several hours and there was a chance that the master node might crash or be decommissioned during that time. Because ZooKeeper recorded the progress on each action, another node could pick up where the master left off in the event of any problem.
  • Centralized configuration management
    Using ZooKeeper to store your configuration information has two main benefits. First, new nodes only need to be told how to connect to ZooKeeper and can then download all other configuration information and determine the role they should play in the cluster for themselves. Second, your application can subscribe to changes in the configuration, allowing you to tweak the configuration through a ZooKeeper client and modify the cluster’s behavior at run-time.
Reference:
http://blog.cloudera.com/blog/2013/02/how-to-use-apache-zookeeper-to-build-distributed-apps-and-why/

http://www.ibm.com/developerworks/library/bd-zookeeper/

awesome read:  https://developer.yahoo.com/hadoop/tutorial/module6.html#intro
-------------------------------------------
group membership:
example
The Group Membership Service (GMS) uses self-defined system membership. Processes can join or leave the distributed system at any time. The GMS communicates this information to every other member in the system, with certain consistency guarantees. Each member in the group participates in membership decisions, which ensures that either all members see a new member or no members see it.
The membership coordinator, a key component of the GMS, handles "join" and "leave" requests, and also handles members that are suspected of having left the system. The system automatically elects the oldest member of the distributed system to act as the coordinator, and it elects a new one if the member fails or is unreachable. The coordinator's basic purpose is to relay the current membership view to each member of the distributed system and to ensure the consistency of the view at all times.
Because the SQLFire distributed system is dynamic, you can add or remove members in a very short time period. This makes it easy to reconfigure the system to handle added demand (load).The GMS permits the distributed system to progress under conditions in which a statically-defined membership system could not. A static model defines members by host and identity, which makes it difficult to add or remove members in an active distributed 

------------------------------------
Note:
write: only through master
read: any nodes can handle it

use: leader election, lock, consensus/voting?
more uses: http://ksjeyabarani.blogspot.com/2012/11/zookeeper-as-distributed-consensus.html
zookeeper recipe: http://zookeeper.apache.org/doc/current/recipes.html

Saturday, May 10, 2014

Notes: Distributed System -- Paxos

what is instance
  • An instance is the algorithm for choosing one value.
  • A round refers to a proposer's single attempt of a Phase 1 + Phase 2. A node can have multiple rounds in an instance of Paxos. A round id is globaly unique per instance across all nodes. This is sometimes called proposal number.
  • A node may take on several roles; most notably Proposer and Acceptor. In my answers, I'll assume each node takes on both roles.

A naive implementation of Paxos is not guaranteed to terminate because multiple nodes can leap-frog Prepare phases. There are two ways of getting around this. One is to have a random backoff before starting new Prepare phases. The second is to route all requests to a designated leader, that acts as proposer (The leader is chosen by a Paxos instance. See also Multi-paxos) 

roundId = i*M + index[node]where i is the ith round this node is starting (that is i is unique per node per paxos instance, and is monotonically increasing).

reference:  http://stackoverflow.com/questions/5850487/questions-about-paxos-implementation/10151660#10151660
----------------------
more paxos: Michael Deardeuff on stackoverflow
pseudo code
http://stackoverflow.com/questions/14435646/paxos-value-choice/14472334#14472334
 --------------------
Round ids (aka proposal numbers) should be increasing and must be unique per instance across all nodes.

-------------------------------
Paxos notes in Chinese
http://blog.csdn.net/m_vptr/article/details/8014220
 -------------------------------------------
No timeout in Paxos???? see below
----------------------------------
finish How to Build a Highly Available System, from section 6.4

------------------------------------------------------
lessons-learned-from-paxos: http://blog.willportnoy.com/2012/06/lessons-learned-from-paxos.html
explained a more practical Paxos

You may even choose to introduce nondeterminism: for example, I use randomized exponential backoff as a response to timeouts to allow a set of Paxos replicas to settle on a persistent leader allowing for faster consensus.

To make code deterministic for repeatable tests, it must have the same inputs. And the same inputs means the same network i/o, thread scheduling, random number generation - effectively all interaction with the outside world.

about timeout in Paxos
  1. Many theoretical algorithms from distributed systems use the Asynchronous Model of time, where there is no shared notion of time across different nodes. One technique used to reduce these methods to practice is to introduce timeouts on certain operations. There would be a timeout for the replica trying to become leader, a timeout for the non-leader replicas watching for a leader replica that has gone offline, and a timeout for the phase 2 rounds of voting. There is an important detail in the last timeout though - the better implementations of Paxos allow multiple instances to reach consensus in parallel (without picking a fixed factor of concurrency, as Stoppable Paxosdescribes). But it simply takes longer, even if purely by network latency, to drive more instances to consensus. So in the end, you either vary your timeout in proportion to the number of requests or you limit the number of concurrent requests so that the timeout is sufficient.

#11 how to avoid massive amount of messages passing in phase1
#15 queue with timeout can work as batching

----------------------------------------




Sunday, May 4, 2014

Hashing

hash function
page 264, clrs
h.k/ D bm.kA mod 1/c

Division Method:
h(k) = k mod m
where m is ideally prime

Multiplication Method:
h(k) = [(a k) mod 2w] (w >> r)
where a is a random odd integer between 2^(w-1) and 2^w, k is given by w bits, and m = table
size = 2r.

universal hashing

----------------------------------
Karp Rabin_wiki, Rolling Hash_wiki

However, there are two problems with this. First, because there are so many different strings, to keep the hash values small we have to assign some strings the same number. This means that if the hash values match, the strings might not match; we have to verify that they do, which can take a long time for long substrings. Luckily, a good hash function promises us that on most reasonable inputs, this won't happen too often, which keeps the average search time within an acceptable range.

hash functions used for karp rabin, go to wiki hash function
The key to the Rabin–Karp algorithm's performance is the efficient computation of hash values of the successive substrings of the text. One popular and effective rolling hash function treats every substring as a number in some base, the base being usually a large prime. For example, if the substring is "hi" and the base is 101, the hash value would be 104 × 1011 + 105 × 1010 = 10609 (ASCII of 'h' is 104 and of 'i' is 105)

multiple pattern search
The Rabin–Karp algorithm is inferior for single pattern searching to Knuth–Morris–Pratt algorithm, Boyer–Moore string search algorithm and other faster single pattern string searching algorithms because of its slow worst case behavior. However, it is an algorithm of choice for multiple pattern search.

------------------------------------------
Probing 
Liner probing
quadratic probing 
Double hashing
h(k, i) = (h1(k) + i * h2(k) mod m



Friday, April 25, 2014

BST - General BST, AVL, LCA

Successor node
#1, with parent pointer
From page 292, CLRS 
TREE-SUCCESSOR.(x)
  if x:right != NIL
  return TREE-MINIMUM.(x:right)
  y = x:p
  while y != NIL and x == y:right
  x = y
  y = y:p
  return y
No need to compare keys

#2, without parent pointer
struct node * inOrderSuccessor(struct node *root, struct node *n)
{
    // step 1 of the above algorithm
    if( n->right != NULL )
        return minValue(n->right);
 
    struct node *succ = NULL;
 
    // Start from root and search for successor down the tree
    while (root != NULL)
    {
        if (n->data < root->data)
        {
            succ = root;
            root = root->left;
        }
        else if (n->data > root->data)
            root = root->right;
        else
           break;
    }
 
    return succ;
}
--------------------------------------------
node insertion
TREE-INSERT.T; ´/
1 y D NIL
2 x D T:root
3 while x ¤ NIL
4 y D x
5 if ´:key < x:key
6 x D x:left
7 else x D x:right
8 ´:p D y
9 if y == NIL
10 T:root D ´ // tree T was empty
11 elseif ´:key < y:key
12 y:left D ´
13 else y:right D ´
node deletion, Page 295, CLRS
3 basic cases:
If ´ has no children, then we simply remove it by modifying its parent to replace ´ with NIL as its child.

If ´ has just one child, then we elevate that child to take ´’s position in the tree by modifying ´’s parent to replace ´ by ´’s child.


If ´ has two children, then we find ´’s successor y—which must be in ´’s right subtree—and have y take ´’s position in the tree. The rest of ´’s original right subtree becomes y’s new right subtree, and ´’s left subtree becomes y’s new left subtree. This case is the tricky one because, as we shall see, it matters whether y is ´’s right child.

Check Wiki for all all operations of BST
"Another way to explain insertion is that in order to insert a new node in the tree, its key is first compared with that of the root. If its key is less than the root's, it is then compared with the key of the root's left child. If its key is greater, it is compared with the root's right child. This process continues, until the new node is compared with a leaf node, and then it is added as this node's right or left child, depending on its key."

----------------------------------------------

AVL, from Wiki
rotation
 if (balance_factor(L) == 2) { //The left column
   let P=left_child(L)
   if (balance_factor(P) == -1) { //The "Left Right Case"
      rotate_left(P) //reduce to "Left Left Case"
   }
   //Left Left Case
   rotate_right(L);
 } else { // balance_factor(L) == -2, the right column
   let P=right_child(L)
   if (balance_factor(P) == 1) { //The "Right Left Case"
      rotate_right(P) //reduce to "Right Right Case"
   }
   //Right Right Case
   rotate_left(L);
 }

Deletion
Steps to consider when deleting a node in an AVL tree are the following:

  1. If node X is a leaf or has only one child, skip to step 5. (node Z will be node X)
  2. Otherwise, determine node Y by finding the largest node in node X's left sub tree (in-order predecessor) or the smallest in its right sub tree (in-order successor).
  3. Replace node X with node Y (remember, tree structure doesn't change here, only the values). In this step, node X is essentially deleted when its internal values were overwritten with node Y's.
  4. Choose node Z to be the old node Y.
  5. Attach node Z's subtree to its parent (if it has a subtree). If node Z's parent is null, update root. (node Z is currently root)
  6. Delete node Z.
  7. Retrace the path back up the tree (starting with node Z's parent) to the root, adjusting the balance factors as needed.

The retracing can stop if the balance factor becomes −1 or +1 indicating that the height of that subtree has remained unchanged. If the balance factor becomes 0 then the height of the subtree has decreased by one and the retracing needs to continue. If the balance factor becomes −2 or +2 then the subtree is unbalanced and needs to be rotated to fix it. If the rotation leaves the subtree's balance factor at 0 then the retracing towards the root must continue since the height of this subtree has decreased by one. This is in contrast to an insertion where a rotation resulting in a balance factor of 0 indicated that the subtree's height has remained unchanged.

The time required is O(log n) for lookup, plus a maximum of O(log n) rotations on the way back to the root, so the operation can be completed in O(log n) time.

---------------------------------------------------------

Red black tree with size attribute in each node, page 341, CLRS

Retrieving an element with a given rank
OS-SELECT.x; i /
1 r D x:left:size C 1
2 if i == r
3 return x
4 elseif i < r
5 return OS-SELECT.x: left; i/
6 else return OS-SELECT.x:right; i r/

Determining the rank of an element
OS-RANK.T; x/
1 r D x:left:size C 1
2 y D x
3 while y ¢¥ T:root
4 if y == y:p:right
5 r D r C y:p: left:size C 1
6 y D y:p
7 return r

--------------------------------------------------
List all keys between two given keys in a bst

LIST(tree;l;h)
lca=LCA(tree;l;h)
result=[]
NODE-LIST(lca;l;h;result)
return result

NODE-LIST(node;l;h;result)
if node==NIL
return
if l <= node.key and node.key >= h
ADD-KEY(result;node:key)
if node.key >= l
NODE-LIST(node.left;l;h;result)
if node.key <= h
NODE-LIST(node.right;l;h;result)

LCA(tree;l;h)
node=tree:root
until node==NIL or (l <= node.key and h >= node.key)
if l < node.key
node = node.left
else
node = node.right
return node

Friday, March 7, 2014

Day 75, ##, Max Points on a Line

Max Points on a Line
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
---------------------------------------------------------------------------------
O(n^2)
/**
 * Definition for a point.
 * struct Point {
 *     int x;
 *     int y;
 *     Point() : x(0), y(0) {}
 *     Point(int a, int b) : x(a), y(b) {}
 * };
 */
class Solution {
public:
    int maxPoints(vector<Point> &points) {
        int maxP = 2;
        if (points.size() == 0 || points.size() == 1) return points.size();
 
        for (int i = 0; i < points.size(); i++) {
            unordered_map<double,int> slopes;
            int samex = 1;
            int samePoints = 0;
            int curMax = 0;
             
            for (int j = i + 1; j < points.size(); j++) {
                double xdistance = points[i].x - points[j].x;
                double ydistance = points[i].y - points[j].y;
                if (xdistance == 0 && ydistance == 0) {
                    samePoints++;
                    continue;
                }else if (xdistance == 0) {
                    samex++;
                    continue;
                }
                 
                double slope = ydistance / xdistance;
                 
                if (slopes.find(slope) == slopes.end()) {
                    slopes[slope] = 2;
                }else {
                    slopes[slope]++;
                }
             
                curMax = max(curMax,max(samex,slopes[slope]));
            }

            curMax = max(samex,curMax);
            maxP = max(maxP,curMax + samePoints);
        }
        return maxP;
    }
     
};