Tuesday, April 26, 2016

Leetcode 146: LRU - Cache

April 26, 2016

Design Last Recently Used Cache

https://github.com/jianminchen/LeetCode-Java-Solutions/blob/master/146.lru-cache.java

C# implementation with one test case:
https://gist.github.com/jianminchen/3dc7da7e0465819e6aa8c10c71901723

Question and answer:
1. What do you learn through the practice?
Use dummy head and dummy tail to help maintain double linked list as cache.

2. Do not forget to set the node to last one when it is visited.

3. Talk about API design:
AddToLast,
set
get - get method is confusing, since it is also to do repositioning of visited node in the linked list - the cache - better to add another function to let get() call,  function - getKeyAndThenMoveToLast
use Dictionary to hold the key value pair,

4. when a node is added to last, with two dummy node in this double linked list, no temp variable needed to set up new connections. Just be patient, dummy tail's prev point: copy, and break, and set a new one.

May 17, 2016
Julia loves this article talking about cache system design; once she does some code review on basic LRU, she starts to enjoy the computer science, she just loves the engineering, good ideas to solve problems.
http://goo.gl/pL5ee4

classical reader/ writer problem / lock / multiple shards/ commit logs/ memcached

June 2, 2016

5. How to design LRU? Data structure? What for?
copy from blog:http://blog.gainlo.co/index.php/2016/05/17/design-a-cache-system/?utm_source=email&utm_medium=email&utm_campaign=email

LRU

One of the most common cache systems is LRU (least recently used). In fact, another common interview question is to discuss data structures and design of an LRU cache. Let’s start with this approach.
The way LRU cache works is quite simple. When the client requests resource A, it happens as follow:
  • If A exists in the cache, we just return immediately.
  • If not and the cache has extra storage slots, we fetch resource A and return to the client. In addition, insert A into the cache.
  • If the cache is full, we kick out the resource that is least recently used and replace it with resource A.
The strategy here is to maximum the chance that the requesting resource exists in the cache. So how can we implement a simple LRU?

LRU design

An LRU cache should support the operations: lookup, insert and delete. Apparently, in order to achieve fast lookup, we need to use hash. By the same token, if we want to make insert/delete fast, something like linked list should come to your mind. Since we need to locate the least recently used item efficiently, we need something in order like queue, stack or sorted array.
To combine all these analyses, we can use queue implemented by a doubly linked list to store all the resources. Also, a hash table with resource identifier as key and address of the corresponding queue node as value is needed.
Here’s how it works. when resource A is requested, we check the hash table to see if A exists in the cache. If exists, we can immediately locate the corresponding queue node and return the resource. If not, we’ll add A into the cache. If there are enough space, we just add a to the end of the queue and update the hash table. Otherwise, we need to delete the least recently used entry. To do that, we can easily remove the head of the queue and the corresponding entry from the hash table.

Eviction policy

When the cache is full, we need to remove existing items for new resources. In fact, deleting the least recently used item is just one of the most common approaches. So are there other ways to do that?
As mentioned above, The strategy is to maximum the chance that the requesting resource exists in the cache. I’ll briefly mention several approaches here:
  • Random Replacement (RR) – As the term suggests, we can just randomly delete an entry.
  • Least frequently used (LFU) – We keep the count of how frequent each item is requested and delete the one least frequently used.
  • W-TinyLFU – I’d also like to talk about this modern eviction policy. In a nutshell, the problem of LFU is that sometimes an item is only used frequently in the past, but LFU will still keep this item for a long while. W-TinyLFU solves this problem by calculating frequency within a time window. It also has various optimizations of storage.
Skip concurrency and distributed cache in this design. 

Next, talk about coding part - data structure and algorithm:
C# implementation. 
https://gist.github.com/jianminchen/3dc7da7e0465819e6aa8c10c71901723

int capacity - specify the size of cache, cache should be with limited size, since resource is limited, specially for high speed access. source code on line 24.

int size - current size of cache - track current size of cache to determine  if eviction is needed or not.
source code on line 24.

Design a double linked list, so ListNode class is defined with two pointers, prev, next
source code from line 10 - line 22.

every entry has key, value. Use int to simplify the coding. Source code, line 12.
line 12   public int key, val; 

Also, we need to add two more variables: dummy head, dummy tail to help maintain the double linked list. source code on line 25.

Also, we need to be able to find the key in O(1) since it is in cache. Extra space is used, maintain a hash map using Dictionary class in C#:
line 27    Dictionary(int key, ListNode)

Let us count how many variables inside the class LRUCache:
6 variables:    - memorize the variable count - 6 - Try to recall.

private int capacity, size; 
private ListNode dummyHead, dummyTail; 
private Dictionary<int, ListNode> map; 

ListNode class as a node in a double linked list: 
 public int key, value; 
 publie ListNode prev, next; 

4 variables.

June 2, 2016
Warm up the algorithm: (a lot of hurdles, just read source code.)
https://gist.github.com/jianminchen/207e20632f7837285ee9b913b0d34f3a

Second warm up the algorithm:
https://gist.github.com/jianminchen/3bd8cdab7a31662d402c62fff9c0b597




Leetcode - 300 algorithms - Learning by Reading Code First

April 26, 2016


Plan to spend next 2 weeks to go over the solution provided by Temple university Ph.D.  Dawei Li


Some leetcode questions to work on first:

1. reverse half linked list
2. priority queue
3. number of island
4. flying ticket
5. unsorted slots with numbers
6. Sum query 2nd mutable
7. word search in matrix
8. course schedule
9. reverse linked list
10. Leetcode 138: deep copy linked list with random number
11. Leetcode 169 Majorith Element I
12. Leetcode 229 Majority Element II
13. Leetcode 218 Skyline


Work on those two algorithms:
insert a node into a sorted linked list
shortest job first.

Leetcode 138:
http://fisherlei.blogspot.ca/2013/11/leetcode-copy-list-with-random-pointer.html

Leetcode 229 
http://www.cnblogs.com/EdwardLiu/p/4179345.html

Boyer-Moore Voting algorithm
https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_majority_vote_algorithm


3 solutions:
http://yuanhsh.iteye.com/blog/2185974

Code Test:
http://www.cnblogs.com/EdwardLiu/category/614910.html

Monday, April 25, 2016

Leetcode 266: Palindrome permutation

April 25, 2016


Study the problem/ solution:

https://github.com/douglasleer/LeetCode-Java-Solutions/blob/master/266.palindrome-permutation.java

https://leetcodesite.wordpress.com/2016/02/08/266-palindrome-permutation/



Leetcode 236: Lowest common ancestor in binary tree

April 25, 2016

Study the code:
https://github.com/douglasleer/LeetCode-Java-Solutions/blob/master/236.lowest-common-ancestor-of-a-binary-tree.java

Julia's C# warm up practice:
1. using Stack class ToArray API, keep the iterator order - stack output order: (5/21/2016)
https://gist.github.com/jianminchen/2bec8a70ef520e715240a226c01c7371

Read Stack class APIs:
https://msdn.microsoft.com/en-us/library/415129w1(v=vs.110).aspx

2. Use List.AddRange(Stack), still keep the stack iterator order
https://gist.github.com/jianminchen/754f45023f60992211cb34bef6d6254f


Compared to Java Stack class APIs later.

Question and answer:

1. What do you learn through the study of the code?

The code is using Binary Tree post order traversal method, and then, to find node p and q common ancestor, work on the stack, get list of nodes from root node to p, same to q, and then, find the common ancestor.

Blog:
http://juliachencoding.blogspot.ca/2015/08/tree-algorithms-review.html

Review:
Post order traversal iterative
https://github.com/jianminchen/leetcode-tree/blob/master/TreeDemo.cs

Write a C# version using exactly same idea.


Leetcode 235: Lowest common ancestor in binary search tree

April 25, 2016

Study the code:

https://github.com/douglasleer/LeetCode-Java-Solutions/blob/master/235.lowest-common-ancestor-of-a-binary-search-tree.java

Walk through less than 10 lines of code, and then add some comment:

    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (p.val > q.val) return lowestCommonAncestor(root, q, p);   // Julia, reduce 2 cases to 1 case: p.val <= q.val
        if (q.val < root.val) return lowestCommonAncestor(root.left, p, q); // two nodes are in the left side of root
        if (p.val > root.val) return lowestCommonAncestor(root.right, p, q); // two nodes are in the right side of root
        return root;   // otherwise, one node is left side, another node is right side: root is the parent. 
    }

Sunday, April 24, 2016

Skip List

April 24, 2016

http://www.geeksforgeeks.org/skip-list/

Plan to spend next 2 weeks to go over the solution provided by Temple university Ph.D.  Dawei Li

https://github.com/jianminchen/LeetCode-Java-Solutions

Some leetcode questions to work on first:
1. reverse half linked list
2. priority queue
3. number of island
4. flying ticket
5. unsorted slots with numbers
6. Sum query 2nd mutable
7. word search in matrix
8. course schedule



Articles to read - big O cheat sheet

April 24, 2016

http://bigocheatsheet.com/

https://gist.github.com/jianminchen/f99280129501be2a702d95882cd62459

http://goo.gl/0JYsZW




Leetcode 314: Binary Tree Vertical Order Traversal

April 24, 2016

Review the algorithm:

Leetcode 314: Binary Tree Vertical Order Traversal


blog:


Back tracking - N Queen problem

April 24, 2016

Review N Queen problem, this one makes me easy to follow:

http://www.geeksforgeeks.org/backtracking-set-3-n-queen-problem/

My own blog:

http://juliachencoding.blogspot.ca/search/label/N-Queens%20problem

Find one problem on HackerRank:

https://www.hackerrank.com/challenges/queens-on-board




Saturday, April 23, 2016

HackerRank: Even Tree (V) C# solution - use queue to help counting spanning tree's node

April 23, 2016

  Problem statement:

https://www.hackerrank.com/challenges/even-tree

C# solutions to study:

Code to study: 

Julia modified the C# code to use DFS, spanning tree's node count, but still got the run time error/ wrong answer. 


Later, find out what is wrong. ( Probably, here is the reason:
The edge is directed. 
Do not duplicate the edge. 
For example, 2 1, just 2->1, do not add 1->2; 
but 
vertex[1].add(2), 
vertex[2].add(1), 
edge just add Tuple(2,1) )

Now, write exactly same code using study code, and see what I can learn.

The following code passes all the test cases.
https://gist.github.com/jianminchen/0e40bb76011e60f8aaf4683ed9c9c3d6

Julia's comment:

The edge is directed. Do not duplicate the edge and save two copy of the edge. But, vertex list is added for both vertexes of one edge.

Follow up - on April 24, 2016 8:40pm
Read Graph Toplogical Sorting:
http://www.geeksforgeeks.org/topological-sorting/

Follow up - on April 30, 2016 11:52pm
Read graph reprenstation
Use Adjacency Matrices
Use Adjacency Lists
https://www.khanacademy.org/computing/computer-science/algorithms/graph-representation/a/representing-graphs

Notes from the blog:
How much space do adjacency lists take? We have |V| lists, and although each list could have as many as |V|-1 vertices, in total the adjacency lists for an undirected graph contain 2|E| elements. Why 2|E|? Each edge (i,j)appears exactly twice in the adjacency lists, once in i's list and once in j's list, and there are |E| edges. For a directed graph, the adjacency lists contain a total of |E| elements, one element per directed edge.

HackerRank: Even Tree - C# solutions to study (III)

April 23, 2016

  Problem statement:

https://www.hackerrank.com/challenges/even-tree

C# solutions to study:
1. 
https://gist.github.com/jianminchen/1858f0b4994efc65c99701290fb951ec

2. written by an engineer in Microsoft
https://gist.github.com/jianminchen/5c6b6cb4de9c4a2faf6237b7ac331a41

3.
https://gist.github.com/jianminchen/3722227eb8c3df4085c10e34779763bf

4. By an engineer in Amazon

https://gist.github.com/jianminchen/8359a5d4f2567db387c0dd80a0f70513

Julia, practice the above 4 solutions. Write it by yourself one by one, and count the time. Work on speed.





  

HackerRank: Even Tree - Graph Problem (II) - Coding first try

April 23, 2016

Problem statement:

https://www.hackerrank.com/challenges/even-tree

Time spent:
over 1 hour,

score 10 out of 50

pass two basic cases, but with run time error after submission on other test cases

https://gist.github.com/jianminchen/455978d2fd4b1ebafb3a5aa7d4761fed


HackerRank: Even Tree - Graph Problem (I) - Just thinking

April 23, 2016

Problem statement:

https://www.hackerrank.com/challenges/even-tree

Motivation to work on graph problem:
1. There are over 10,000 submission on this problem, definitely, Julia likes to give it a try.

Statistics:
1:20 - 2:30pm  more than 1 hour wild thinking.

Think about the graph problem, before Julia writes any code, she think about how the problem is developed:

1. Have to remove as many edges from the tree as possible; <- kind of greedy algorithm
2. Each connected component of the forest should contain an even number of vertices.
<- Otherwise, odd number, 1 node itself, cannot be called forest; at least, 3.
3. Think about the how to remove one edge:
both ends should be ok; if one end only has one edge, then, no for removing the edge.
so, the node checks its edge count:
= 0 <- not possible - > "even number of vertices"
= 1 <- impossible
= 2 <- possible, can keep one, remove one

But think about forest with even number 2, 4,
for number 2, only one case:  3 connects to 4 in the test case
for number 4, only one case: one node in the center, all other 3 are connected to the same one.
for number 6, only one case: one node in the center, all other 5 are connected to the same one;
otherwise, one node connects to other 4 nodes, the 6th one will connect to the one of the node (other 4 nodes), then, it can be break into 2 and 4.

So, it should be two checking:
1. if the node only has one edge, keep it; do nothing;
2. if the node has more than one edge, remove all edges with more than 1 count.


Add comment on 10:00pm on April 23, 2016
1. Julia, you took distributed system in Florida Atlantic University around 2001, talking about spanning tree, ad hoc routing protocol; one thing is about spanning tree. Use DFS, and then, discuss spanning tree; if the root node's  child has a tree with even length, then, edge can be removed.

Friday, April 22, 2016

Find if a Directed Acyclic Graph has a cycle.

April 22, 2016

Find if a Directed Acyclic Graph has a cycle. Use DFS with coloring to find if cycle exists.

Given a directed graph of 10 cities, each of which may or may not be connected to each other, represented by an adjacency list, write an algorithm to find if there is a write from a city that eventually cycles back to the same city. What is the time complexity of your algorithm? You may use reasonable extra storage, or modify the structure of the graph node class.

Question and Answers:

Julia, read a few blogs, and then quickly go over first time. 30 minutes:
1. https://www.quora.com/How-can-DFS-and-BFS-be-used-to-find-out-if-there-are-cycles-in-a-graph

2. http://www.geeksforgeeks.org/detect-cycle-in-a-graph/
Take notes here:
Depth First Traversal can be used to detect cycle in a Graph. DFS for a connected graph produces a tree. There is a cycle in a graph only if there is a back edge present in the graph. A back edge is an edge that is from a node to itself (selfloop) or one of its ancestor in the tree produced by DFS. 


In other words, Julia, using DFS, to detect the cycle; 
DFS for a connected graph produces a tree; So, from graph -> DFS -> Tree
Then, work on Tree, to see if there is a back edge present in the tree; 
What is back edge? How to track? ancestor node in a stack - using array. 

Question and Answer: 
Walk through the code, and add the comment: 
https://gist.github.com/jianminchen/2eea7cc7cca69f296fc105c3fc3faafa

Read another blog:
http://www.geeksforgeeks.org/depth-first-traversal-for-a-graph/

Read another blog from HackerRank:
https://www.hackerrank.com/topics/topological-sorting

Actionable item:

Work on HackerRank graph problem today:
https://www.hackerrank.com/challenges/even-tree

And then, study as many as possible solution about this graph problem. Get ideas how people are talented on graph problem solving.






Find the lowest common ancestor of two nodes in a Binary Tree.

April 22, 2016

Find the lowest common ancestor of two nodes in a Binary Tree. The tree does not have a parent pointer. Your algorithm should run in linear time, without any extra space.

Bottom-up approach.

http://www.geeksforgeeks.org/lowest-common-ancestor-binary-tree-set-1/

HackerRank problem:

https://www.hackerrank.com/challenges/binary-search-tree-lowest-common-ancestor

https://www.topcoder.com/community/data-science/data-science-tutorials/range-minimum-query-and-lowest-common-ancestor/


Review blog:
http://juliachencoding.blogspot.ca/2015/07/leetcode-lowest-common-ancestor-in.html

Tortoise-hare algorithm

April 22, 2016

Find if a linked list has a cycle. Expectation O(n) time; O(1) space.

http://codingfreak.blogspot.com/2012/09/detecting-loop-in-singly-linked-list_22.html

https://www.quora.com/How-does-Floyds-cycle-finding-algorithm-work



Fisher-Yates algorithm

April 22, 2016

A deck of cards is represented by an integer array of size 52, with possible value of 1 - 13 for each position. Design an algorithm to shuffle the deck of cards in linear time, in-place.

https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

April 26, 2016
http://www.geeksforgeeks.org/shuffle-a-given-array/

“shuffle a deck of cards” or “randomize a given array”

Question and answer:

1. Understand the naive approach, extra space - an array, and also time O(n^2).

2. Came cross this blog <- So, use Fisher-Yates algorithm

大概就是取一个array里的任意n个不同的值,得到一个随机的组合,不能取同一个index的数,但是可以取数值相同的不同index的数

给一个array:[5,1,3,3],
再给一个数字n:2,
求这个array里的任意num个数:比如可以得到[5,1] or [5,3] or [1,3] or [3,3] ,但是不能得到[5,5]

再比如[5,1,3,3], 1 ===> [5] or [1] or [3]

就是先判断如果n>array.length或者n<=0或者array是空,返回一个空array
否则就是一个loop,每一次生成一个random的index数字,还用了一个hashset来存之前访问过的index,如果生成的random index之前已经get了,就再继续生成一个random index。
loop n次,每次取到的值放进新的结果array里。.鐣欏璁哄潧-涓€浜�-涓夊垎鍦�
然后说了说也可以用一个boolean array存每个值有没有已经取到。。
写完后再写了写unit test什么的,还有问道怎么检测得到的结果比如[5,1]确实是[5,1,3,3]里的
Julia's comment: 
3 issues:
1. In place - no extra array 
2. Hashset is also extra memory 
3. Work on array index - random number selection using % operator, not on value in the array. 

3. Let us walk through the code and then add comments - make it fun memory:
// A function to generate a random permutation of arr[]
void randomize ( int arr[], int n )
{
    // Use a different seed value so that we don't get same
    // result each time we run this program
    srand ( time(NULL) ); // Julia, Good to know, C++, look up srand API
    // Start from the last element and swap one by one. We don't
    // need to run for the first element that's why i > 0
    for (int i = n-1; i > 0; i--)
    {
        // Pick a random index from 0 to i
        int j = rand() % (i+1); // Julia: random number -> Range (0, i) using module
        // Swap arr[i] with the element at random index
        swap(&arr[i], &arr[j]); // swap two nodes
    }