Showing posts with label trie. Show all posts
Showing posts with label trie. Show all posts

Monday, July 24, 2017

Boggle - find words in matrix of letters

July 24, 2017

Plan to study the algorithm Boggle coding blog. The blog link is here written by Aviad Ezra.

There are a lot of thing for Julia to learn through those blog and code sample. Let us read words from Aviad Ezra together in the following:

Learn: Cracking the interview, solve all 189 questions.

Practice: Nothing beats mock interviews. It will boost your confidence and you’ll learn a ton from having someone watching you and listening to your explanations while you solve coding problems. You can pair with a friend or use one of the free peer-to-peer mock interviewing platforms. You don’t need to sacrifice your first interviews just to get hands-on practice.

Think fast: Developers that can think on their feet do much better in coding interviews. Practice in as many competitive programming sessions as you can.

Before you lost hope, keep in mind that there's a finite number of algorithms topics and only a handful of data structures that are used in the interviews.

Those words from  Aviad Ezra are so encouraging, Julia wrote her own blog about "Can mocking make difference?". First time she learns to work with people, share with people, learn from people on small things, like presenting her face in the centre through the video, ask good questions, give good hint, form a quick friendship etc.

In the following, Julia uses Leetcode 212 to help herself review Trie data structure and learn how to apply same algorithm as Boggle classified in Leetcode.



Leetcode 212 - word search II


Review Leetcode 212 last practice using Trie. The link is here.

It is so surprising that learning Trie and practice depth first search is most fun activities in the summer of 2017. Julia has to warm up the algorithm, play with one test case with Trie class, and also make the code more readable. Here is the warmup C# code using Trie data structure, recursive function calls. The solution is optimal and also pass online judge.

It is also a good idea to discuss why Trie is needed for better time complexity.

Brute force solution is to go over each word in the dictionary, and then try to find it in the matrix. The total number of search using DFS is m (words) * rows (matrix) * columns (matrix).

The brute force solution has timeout issue through Leetcode online judge. We like to review why the time complexity should be better.

Let us go over dictionary with 4 words, "aaa", "aaaa","aaab", "aaac". If we pre-process the dictionary and store all words in a Trie, and then we do not have to go over each words to search matrix. We only need to go over each element in matrix as start char in a word, search the trie to find match words using recursive function. The number of search using DFS is rows (matrix) * columns (matrix).

Second advantage related to the above 4 words ( "aaa", "aaaa","aaab", "aaac") is taking advantage of Trie data structure. The space complexity of Trie is better compared to hashset or hashtable. The same prefix "aaa" is only repeated once in the Trie.

This hard level algorithm applying Trie will be Julia's most favorite algorithm in the month of July 2017.

One of practice in 2017 is prefix neighbor on hackerrank, Julia asked the code review on stackexchange.com.


July 26, 2017

Trie against Hashset


Related to the test with a dictionary "aaa","aaaa","aaab","aaac","aaad", let us work together to talk about the difference.

For example, if the dictionary is saved in hashset, then go over each word in the dictionary, try to find word in matrix.
For example, "aaab", the first three letters has to be compared and they are the same first, then the last letter will be checked. Same will be applied to another 4 words. In total, the prefix "aaa" will be compared exactly 5 times in order to find those 5 words.

Can we do better? Just compare the prefix "aaa" once? Cetainly we can. We can save the words in a trie instead of hashset.

a
|
a
|
a
|\  \  \
| \  \  \
|  \  \  \
a  b  c  d



Trie efficiency talk 



It takes some time to get comfortable to design a Trie. So far, Julia has written a Trie implementation more than 4 times in C# last 3 years. Given the fact that she has worked on computer science more than 20 years, if she writes a algorithm every day, then she will write 60,000 algorithms. It is smart to focus on one simple thing, write code for algorithm and data structure, no matter life goes up and down, make it a hobby.

How to design a Trie so that the space complexity is minimum?
For example, the dictionary has the following words, "aaa","aaaa","aaaaa","aaaaaa".
How to store them in Trie efficiently?
a
|
a
|
a   word: "aaa"
|
a   word: "aaaa"
|
a   word: "aaaaa"
|
a   word: "aaaaaa"

The above diagram shows that those four words are saved in a Trie. How many char 'a' are saved in Trie, only 6, not 3 + 4 + 5 + 6 = 18 chars. Four words are saved along the trie nodes.

Every node can represent a word, it does not have to be a leaf node.

It is a smart decision to write down some test cases, so next time when Julia comes cross an algorithm, she can quickly relate to the test cases and figure out the advantage of using Trie.

Tuesday, June 13, 2017

Leetcode 212: Word Search II

June 13, 2017

Problem statement

Introduction



Trie is the kind of tree data structure and easy to save space with common prefix. Julia spent over 5 hours to work on one of trie algorithm and posted a code review on stackexchange.com called prefix neighbor. She went through the trie and learned that the trie can be in any form.

This time Julia had to relearn trie again. She had the weakness of data structure Trie, she could not figure out how to solve test case 36 and 37 two test cases timeout issue.

Code practice 


It is the hard level algorithm.

Julia worked on the Leetcode 212 word search.

Her first submission failed last 2 test cases from 36 - 37. Timeout issue. Julia did not know that she needs to use trie, she just used recursive function. The code is here.

Here is the C# code.

She studies the discussion written by a Googler - Yavinci, and wrote second practice. Still work on the code for more testing. Here is the C# code.

Julia continued to work on the trie and here is the C# code passing leetcode online judge.


Algorithm talk - learn Trie again



It is interesting to learn how data structure Trie to help solving timeout issues. For example, there are a lot of words like "aaaa", "aaab", "aaac", ...,"aaaz", Julia was so naive on June 13, 2017. She just goes over each word in the dictionary, and try to find each word using depth first search (DFS) recursive calls.

However the last 2 test case of 37 test cases time out. But Julia did not have idea how to solve it.

Julia needs to take a data structure coaching lesson again. so great to catch the opportunity.

As we can see, those words have same prefix "aaa", and the fourth char or last char is a to z. How to save the time to search, for example, if the path is the prefix of one word, then we need to continue to search.

Think about time complexity. My original solution (the C# code) is to go over each word, and then start to search board using DFS; so time complexity is related to how many words, each word is searched through board using DFS. If 26 words all starting from same prefix "aaa", then "aaa" will be searched in the board over 26 times.

The idea of using Trie, and then go over each element in the board, and then do DFS search against the Trie tree.

So preparation is the key, store all words to a prefix tree first.

Trie 


Plan to read Trie wiki article, review time complexity advantage of using Trie data strucutre.

A trie has a number of advantages over binary search tree. A trie can also be used to replace a hash table.

Topcoder using Trie - the article link is here.
Hackerearth tutorial about Trie - the article link is here.
Read 10 pages lecture notes about Trie - CMU lecture notes is here.

Sunday, February 12, 2017

Hackerrank RookieRank 2 - prefix neigbhors (II)

Feb. 12, 2017


After the contest, Julia likes to study a few of solutions in C#, Java and other languages.

Code study of submissions


C# code

C# code.

Have some difficulty to understand the algorithm behind Index.Add method. Need to figure out later. Add some test cases to C# code, debug and understand the code one line by one line.

Study a few things about C# coding style, pascal case, set, get, and then using GroupBy, OrderBy, Aggregate, Stack, HashSet, Dictionary.

Second Study 

C# code study II
C# code is here

Third Study 


Java implementation

Problems

The most readable code is here with trie implementation. Julia chose one solution from near 100 solutions, this one is easy to follow. Will rewrite the C# solution based on this Java implementation.

Actionable Items



1. Instead of studying other people's code, Julia decided to look into test case 11 and figured out why her submission failed the test case. 

2. Read editorial notes from hackerrank, understand the idea, google search them:

This problem can be solved using Trie and DP. Create a trie from the given set of strings. Find the prefix neighbor of each string. Now create a graph such that each string is a node and there exist a bidirectional edge between two nodes only if they are prefix neighbors. Now find the maximum weighted independent set.

Statistics
Difficulty: Medium
Time Complexity:

O(N*max_length_of_string)
Required Knowledge: Trie
Publish Date: Mar 25 2016


Read the wiki article - Independent set ( graph theory)
GeeksforGeek problem - Largest independent set problem

3. Julia did not know the importance of problem solving in the contest and after the contest from Feb. 11 - 13, 2017. She tried to understand the other people's submission after the contest, and she had difficult time. She needs to understand the algorithm first, just follows the notes: find the maximum weighted independent set

4. Spent over 2 hours to rewrite the C# code, and post
 a question on stackexchange.com.  

Problem solving - community help


Feb. 25, 2017 5:27pm

With the help from Peter Taylor through his code view, Julia learned so much about the problem solving skills. She answered code reviews one by one, and then felt so comfortable with the algorithm problem solving. The code review experience is top-rated performance. 

Share some comments here:

Advice #6, KISS, why? what is wrong to insert them all into one trie? This is a good question. I tried to use the above code, but use one trie instead of going through A to Z one by one, run the code on hackerrank, error from test case 6 to 19; And then, I tried not to sort by the length of string, error from test case 6 to 19. – Jianmin Chen Feb 15 at 5:06   

Very good review, I did spend over a few hours in the contest and also a few hours after the contest. I like the last review "KISS, why?" most, remind me 5 whys for root cause analysis. Bravo! – Jianmin Chen Feb 15 at 5:11  

Hackerrank RookieRank 2 - prefix neighbors (I)

Feb. 12, 2017

Problem statement

Julia spent a day to work on the algorithm in the contest, Feb. 11, 2017. She reviewed her previous practice on trie, and then solved the algorithm to gain 14 out of maximum 50 points.

Her C# code is to create a trie to go over all strings, and then set each string to an array with size 11. Since the string's length is less and equal to 11, go over each length from 11 to 1, and then add those nodes to selected subset, set prefix neighbor node to exclude.

Actionable Items:

In the contest, Feb. 11, 2017, Julia spent over 3 hours to study the algorithm, over 2 hours to work on her trie implementation C# code in Sept. 7, 2016, make it more readable.

And then, Julia also spent over 3 hours to work on C# code to solve prefix neighbor algorithm. This is the perfect practice Julia learned to solve. It is out of her comfortable zone, and then she started to think on her feet and figured out something working.

More concerns about time spent, Julia should spend time wisely.




Saturday, February 11, 2017

Hackerrank Rookierank 2 contest

Feb. 11, 2017

Introduction

Julia got excited. She still has 20 hours to go, and she only needs to work on last algorithm with medium level. She likes to document her practice starting from 12:42pm, how does she do to study, research, and catch up, and make some points from maximum 50 points.

Let us review what she has done so far, compared to the top 1 ranking player.


Some facts to share:
1. The last algorithm can be implemented in 20 minutes by the top performer.
2. The KnightL on a Chessboard is implemented by the top performer in 34 minutes; Compared to the best one, Julia spent 160 minutes.

Practice in the contest

Julia likes to work on the algorithm Prefix Neighbors, try to make things simple as possible. She started from 12:25, and then spent 3 hours to work on the algorithm.

Progress report 

12:25 - 3:22pm - Feb. 11, 2017

Discussion about sorting strings, radix sorting is a good idea to try. More detail, I think that string sorting is using radix sorting. The test case 4 A ABC AC ACD is sorted by 26 O(N), N <= 11.

Passed first 10 test cases

Worked on the coding from 7:00pm - 12:00pm, and then fixed bugs until 2:26am. Gave up. Learn a ton of patience, develop some skills. 

Here is the comparison: 




Coding is like tennis sport

Julia likes to work hard on the algorithm problem solving. So, she plans to take a break 1 - 2 hours first and then continue to work on the algorithm. 





Have 30 minutes workout to relax first, 90 minutes shopping trip. Saturday is the fun day. 

Try to remember the whole paragraph: 
frustrating sport, 
no way around the hard work, 
embrace it, 
put int the hours to improve somethings, 
a lot of sacrifice and effort
sometimes little reward, 
but you have to know that, if you put in the right effort, the reward will come.