Thursday, April 28, 2016

HackerRank: Bear And Steady Gene - binary search algorithm (VI)

April 28, 2016

Previous blog on binary search on Bear and Gene algorithm:

Come back to the problem on binary search solution, figure out the design:


Problem statement:

https://www.hackerrank.com/contests/hourrank-6/challenges/bear-and-steady-gene  

A gene is represented as a string of length  (where  is divisible by ), composed of the letters , and . It is considered to be steady if each of the four letters occurs exactly  times. For example,  and are both steady genes.

Study code using binary search:

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

https://gist.github.com/jianminchen/395eb9e76fe19cc9338f

Comment:
Binary search is better than linear search using two pointers.

Brute force O(n^2) -> linear search O(n) -> Binary search O(logn) <- Not True!

Java code:
https://gist.github.com/jianminchen/d01faa03ca9b06696db3
C# code
https://gist.github.com/jianminchen/76dffc51880a80279f25

First, go through two test cases: "GTTCCAAA" and "GAAATTCC"

1. "GTTCCAAA",

Binary search is doing this way:
Biggest value of search string length is 8.
First, divide range from 0 to 8 into half, 4
Find first string with length 4,
one is "GTTC", one is "CAAA",
and then, remove count of first half, rest string (two parts, seperated) "CAAA", since A is repeated 3 times, not in the range;
instead of stopping, wrongly conclude that 4 is not high value, go through all the possible substring with length 4, by sliding window of search string: "GTTC" forward from left to right, but keep the same window size
"GTTC" -> "TTCC"->"TCCA"->stop here, since "TCCA" is removed from counting of GENES="ACGT", fit into the requirement.

Next, low=0, high=4, mid = 2,

Because both test cases with one 'A' to replace, Julia figured out through the debugging:

The slide window of fixed length technique,
How to slide?
Which direction to slide?

Kind of clever in design.
Time complexity analysis: length search using binary search, n - length of string, O(log n) times; each search for length m, go over each string once, since using calculated counting array, only do add one/ remove one at a time, one char only does the work once. So, it is O(n) on this.

Total time complexity: O(n logn)
Conclusion: this binary search is not better than linear search is previous blog (IV). 

Wednesday, April 27, 2016

The art of readable code - book review second time

April 27, 2016

 Julia spent one month to go over the book, use it to do some code review in 2014. So, write down things learned from her favorite book:

 http://www.amazon.com/Art-Readable-Code-Theory-Practice/dp/0596802293

  chapter 5: Knowing what to comment
  chapter 6: Making comments precise and compact
  chapter 7: Make control flow easy to read <- 9 out of 10
  chapter 8:  Break Down giant expression  <- 10 out of 10
  chapter 10: Extracting unrelated subproblems <- Favorite (8/ 1-10)
  chapter 11: One task a time <- Should follow the idea more closely

 Later, compare to "Clean Code" book, write a few words to share.

A blog about naming variable: (10-15 minutes reading)
http://a-nickels-worth.blogspot.ca/2016/04/a-guide-to-naming-variables.html

Clean Code - book reading

April 27, 2016

 Julia was recommended to read this book "Clean Code". So, plan to read the book in next 2 weeks.

 Put some notes together on this blog.

http://goo.gl/hHBZPS

Short slides about the book: clean code

Nov. 15, 2016
Spent 1+ hour to read the chapter 3:
Chapter 3 - Functions
small
do one thing
one level of Abstraction per function

Julia likes to google and work on those 3 key concepts.

Google search:
Keyword:
one level of Abstraction per function

http://principles-wiki.net/principles:single_level_of_abstraction

HackerRank: Bear Steady Gene (II) - Better Code

March 4, 2016


  Problem statement:

https://www.hackerrank.com/contests/hourrank-6/challenges/bear-and-steady-gene  

A gene is represented as a string of length  (where  is divisible by ), composed of the letters , and . It is considered to be steady if each of the four letters occurs exactly  times. For example,  and are both steady genes.

Julia's 1st practice:

https://gist.github.com/jianminchen/80723bae951328a690bb

score 15 out of 50, there are 2 run time error, failed a few of test cases.

The algorithm ends up in time complexity O(n^2), close to brute force solution - O(n^2)

C# code implementation to study:

Readable code, with some analysis.

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

Work on two pointers, sliding window, so time complexity is O(2n) = O(n).

Let us go over two pointers algorithm here using example:
GAAATAAA,
A - count of A, denoted as cA = 6, n/4 = 2, so we have to change 4 of A to other thing.
A - 6 -2  = 4 , 4 of change
C - 0 - 2 = -2
T - 1 -2  = -1
G - 1-2  = -1
So, at least minimum is 4, but a substring containing 4 of A, shortest one is AAAA. But "AAAA" is not a substring of "GAAATAAA"

G  A A A T A A A
0
start
end
Let us find the substring starting from 0, but will include all 4 of A, and then, rest of string will not include any char of "ACGT" more than n/4.
GAAATA, string length is 6.
start - 0, index of 0
end - A, index of 5

continue to move start to next one, 1, then, G is moved out from substring, adjust count of chars.
AAATA can be the substring, so the length is min (6, 5) = 5. Do not need to move end pointer.

next step, start = 2, missing one of A, and then, end has to move to next one until the string fits into requirement.

Every thing should be covered in 20 minutes, problem reading, the design of algorithm, the coding.

So, Julia had second practice, and the code scores 50 out of 50 this time.

https://gist.github.com/jianminchen/61dfe437f82edb9793fc

April 27, 2016
Change C# program to make variables more meaningful, matching the design:
code -> GENES <- global string array
function name matches design of two pointers moving.

Improvement 1: 
Third practice: 
https://gist.github.com/jianminchen/b8263048c297473319c23836e9468c14

Improvement 2: 
Fourth practice:
searchStrArray -> searchStrNumbers, more meaningful.
https://gist.github.com/jianminchen/b23c4f606a101b9aeec71eff3268db32

Comment: (April 27, 2016)
Spend some time to read "clean code", get some ideas to write better code. 


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