Showing posts with label Leetcode 126: word ladder II. Show all posts
Showing posts with label Leetcode 126: word ladder II. Show all posts

Thursday, April 19, 2018

Leetcode 126: Word ladder II

April 19, 2018

Introduction


It is the hard level algorithm and I like to spend time to go over a few more ideas through Google search and Leetcode discussion panel. What I like to do is to go over more detail how to address time and memory limit exceeded problem.

I spent over 30 minutes already to go over my past practice and a few ideas, I like to go over this blog.

Algorithm practice


I like to go over the notes written in Chinese in the blog, and then rewrite some of them, make it my own.

As a programmer, most of important for me right now is to be a good thinker. I like to search the blogs and find the idea to help me think clearly. Here is the notes:

LeetCode中为数不多的考图的难题。尽管题目看上去像字符串匹配题,但从“shortest transformation sequence from start to end”还是能透露出一点图论中最短路径题的味道。如何转化?

1. 将每个单词看成图的一个节点。
2. 当单词s1 改变一个字符可以变成存在于字典的单词 s2 时,则s1与s2之间有连接。
3. 给定s1和s2,问题I转化成了求在图中从s1->s2的最短路径长度。而问题II转化为了求所有s1->s2的最短路径。


How do I go over the notes above? 

1. Google search the shortest path in the graph. 
2. How to define a graph? Every word is a node in the graph. 
3. Node s1 and node s2 have a connection -> how to define it?

Let me work on the notes in the following:

无论是求最短路径长度还是求所有最短路径,都是用BFS。在BFS中有三个关键步骤需要实现:

1. 如何找到与当前节点相邻的所有节点。
这里可以有两个策略:
(1) 遍历整个字典,将其中每个单词与当前单词比较,判断是否只差一个字符。复杂度为:n*w,n为字典中的单词数量,w为单词长度。
(2) 遍历当前单词的每个字符x,将其改变成a~z中除x外的任意一个,形成一个新的单词,在字典中判断是否存在。复杂度为:26*w,w为单词长度。
这里可以和面试官讨论两种策略的取舍。对于通常的英语单词来说,长度大多小于100,而字典中的单词数则往往是成千上万,所以策略2相对较优。

2. 如何标记一个节点已经被访问过,以避免重复访问。
可以将访问过的单词从字典中删除。

3. 一旦BFS找到目标单词,如何backtracking找回路径?



Monday, May 30, 2016

Leetcode 126: word ladder II - using BFS - Queue, Set Paths (Practice VI)

May 30, 2016

Study the blog:
http://juliachencoding.blogspot.ca/2016/05/leetcode-126-word-ladder-ii-study-c.html

And continue to write C# solution - focus on coding, design ideas.
1. First practice, with a bug on just after line 111 - missing to add tmpList to newList.
https://gist.github.com/jianminchen/9e45848c86ebaaa8f0bc0d881cfd1ad5

2. Fix the bug and pass the test case, add line 112:
https://gist.github.com/jianminchen/e3466a9f1319f62f869aa53487c05536

Questions and Answers:

1. How is the practice?

Here are some sharing:
1. Write down the comment about the idea to solve the problem, from line 23 - line 58

Good idea is to solve 50% of problem. Repeat the idea in the following:

Explain the idea using the test case:
     
                             dot -> dog
          hit->hot ->                    -> cog
                              lot -> log
          so, the queue process is (breadth first search)
          first  layer:        hit
          second layer:   hot
          third  layer:      dot, lot
          forth  layer:      dog, log
          fifth  layer:        cog
          
          build ladders step by step, from startWord to current. 
          
          Dictionary<string, List<List<string>>> ladders
          
          each string will be the key in ladders
          hit -> hit
          hot -> one list, {"hit", "hot"}
          dot -> one list, {"hit", "hot", "dot"}
          lot -> one list, {"hit", "hot", "lot"}
          dog -> one list, {"hit", "hot", "dot", "dog"}
          log -> one list, {"hit", "hot", "lot", "log"}
          cog -> two lists,
                           {"hit", "hot", "dot", "dog", "cog"}
                           {"hit", "hot", "lot", "log", "cog"}

2. Some highlights?

First of all, first writing is wrong. There are 5 levels, 4 loops and then one if, Julia got confused the position of code.
So, marks are added in the comment just after the loop - start statement and also close }.
Work on indentation - Better to write down your own marks. 

line 75   // level 1, while loop
     line 88   // level 2, for loop
          line 93   // level 3, for loop
                  line 97   // level 4, for loop
                      line 104  // level 5, if statement
                      line 121 //  end of level 5, }
                  line 122 // end of level 4, }
          line 125 // end of level 3, - end for loop for hop string length
    line 128   // end of level 2, - processing - all nodes in the same distance in the queue
line 139  // level 1 - processing queue - queue.Count > 0

line 95, char variable name: char backtracking_char, just friendly remind to do backtracking later on line 124.

line 102, string variable name change: newstring -> nextHop, hopefully the current one is more meaningful.

3. Actionable items?

Write again a few times, try to finish coding in 30 minutes, and write down issues not resolved.
Coding is like sports, just do it! 

4. More to share about the algorithm?

Share one graph to illustrate the graph problem of word ladder:
5. A lot of people complained the problem is too tough. Julia, you miss the most important things in the design?
Time out is a big issue. And also, we need to discuss how to avoid a cycle in the list; multiple paths can be found from start word to end word.
Challenge 1:  The visited word must be removed sometime to avoid a cycle;
Challenge 2:  When to remove visited words from dictionary properly? Same distance, one word can repeat multiple times.

Sure, let us talk about it!
on line 84, inside the while loop, Hashset<string> nextHops_BFS are defined. We need to examine this Hashset:
on line 120, nextHop is added one by one to the HashSet, but no action is taken on the HashSet. Lazy processing here!
Until all nodes in the current layer are processed, dequeue from the queue. From line 133 - 137, add next layer hops into the queue, where to find the nodes - nextHops_BFS . Remove the words from wordList just before adding to the queue.

Put line 135 just after line 120, and see what is difference.
The program will generate no output for test case:
                              dot -> dog
          hit->hot ->                    -> cog
                              lot ->  log

log word's next layer is cog, and dog word's next layer is cog as well. Both routes have same word, terminate word. cog can not be removed from wordDist Hashset until two routes are processed both. Actually, the graph should look likes the following: 
     
                             dot -> dog -> cog
          hit->hot ->                   
                              lot -> log -> cog 

In fifth layer, cog word shows up on line 102 twice:
line 102 if (wordList.Contains(nextHop))
So, 2 lists can be added with the same word "cog" as last one.

It is important to keep wordList untouched until the whole layer is processed, then, remove
words in HashSet nextHops_BFS from wordList. 

Rules to obey in the design:1. The same word does not repeat twice in the same list. For example, hit->hot->lot->log->lot-log..., it may go on forever. 

2. One word does not show up in more than one list, except start word and end word. For example, test case, hit, cog are only exceptions. 
Not True. "hot" shows up in two lists. 

3. Words in the distance n should not be any word in distance 0 to n-1. 
                             dot -> dog
          hit->hot ->                    -> cog
                              lot ->  log

So, when dog or log are processed in the queue, all words less than 4, hit, hot, dot, lot should be removed from HashSet wordList. 
Need to go through those cases one by one. 

Actionable items:
Read the blog and then implement the solutions as well.
http://www.cnblogs.com/shawnhue/archive/2013/06/05/leetcode_126.html



Sunday, May 29, 2016

Leetcode 126: Word Ladder II - warm up practice (II)

May 29, 2016

 Share one tweet from profession tennis play Angelique Kerber (2016 Australian Grand Slam champion):
https://twitter.com/AngeliqueKerber/status/734019444868059136

"Everyone asks me what's next. I'm here to stay, taking it one game at a time."


 One algorithm at a time. Still work on Leetcode 126: word ladder II,

 Here is the practice version on May 28, 2016, less than 15 hours ago.
http://juliachencoding.blogspot.ca/2016/05/leetcode-126-word-ladder-ii-warm-up.html

 And then, she spent over 2 hour to make changes on the code, here is the new version:

https://gist.github.com/jianminchen/90075ee13a6ad0d9d59c8843d17e3a18

 Here are the list of things she made the change:
1. line 21, class member variable is commented out. ladders.
    It is replaced by an argument in the function:
line 189 getLadders_DFS_Backtracking, 8th argument - ladderHelper

2. line 27, comment out member variable ladderHelper, pass an argument in
function getLadders_DFS_Backtracking line 189, last argument: List<string> ladderHelper

3. line 60, change function name to getLadders_DFS_Backtracking, remind myself two things:
1. it is a DFS algorithm
2. Do not forget to do backtracking

4. line 102, change function name to getLadderLengthAndDictionary_BFS. BFS stands for 
breadth first search.

5. line 203, line 204, add two more explanation variable, make code more readable.
isEndWord, 
isBeforeEndWord

6. line 220, add explanation variable, backtracking_char, helps user to understand 
the backtracking process.

7. line 221, add explanation variable replace, the char will be replaced by any one of from 'a' to 'z'.

8. line 225, 226
if(j == replace)
  continue;

Make the code more flat, no nested two if statements, only one if statement.

9. line 229, ij_word, ij prefix helps to track index i and index j.
10. line 245, line 249, line 251 3 backtracking statements.





Saturday, May 28, 2016

Leetcode 126: word ladder II - warm up practice

May 28, 2016

  Share professional tennis player Kristina Mladenovic tweet:
https://twitter.com/kikimladenovic/status/732966170375114752

I know what it takes to win. Forget everyone else and put the work in.

Spend one hour to work on the word ladder II, Leetcode 126.
Previous blog:
http://juliachencoding.blogspot.ca/2016/05/leetcode-127-word-ladder-medium_24.html work on one test case:
hit-> cog
Dictionary<string, int> has entries:
Let us talk about a test case to help understand the work:
           hit -> cog
           Two transformation paths:
                         dot -> dog
           hit -> hot ->            -> cog
                         lot -> log
                         
           dist value is 5
           Dictionary<string, int>
           key    value      new value
           hit     0            4
           hot     1            3
           dot     2            2
           lot     2            2
           dog     3            1
           log     3            1
           cog     4            0

Extract a function called resetDistanceFromEnd

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