-
Notifications
You must be signed in to change notification settings - Fork 7
425. Word Squares #375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
425. Word Squares #375
Conversation
| matrix[i][rowIndex] = ch; | ||
| int letterIndex = letterIndex(ch); | ||
| if (trieNodeState[i].children[letterIndex] == null) break; | ||
| trieNodeStateNext[i] = trieNodeState[i].children[letterIndex]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that trieNodeStateNext doesn't do anything. If I'm not mistaken, we can remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has a function as a kind of "backtracking" to the older "trieNodeState" keeping the older state immutable.
But, we can try removing of course.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't see it being inputted into dfs. It makes more sense now, as we are traversing after some prefix already gone through.
| TrieNode[] trieNodeStateNext = new TrieNode[trieNodeState.length]; | ||
| for (String candidate : trieNodeState[rowIndex].list) { | ||
|
|
||
| if (isSymmetric(matrix, candidate, rowIndex, trieNodeState, trieNodeStateNext)){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: isSymmetric() method handles the backtracking part too. As we call the method, it overrides the character matrix with the candidate string. If it's okay, we continue with it. If it's not symmetric, we don't. Either way, it get's overriden in the next function call.
| matrix[i][rowIndex] = ch; | ||
| int letterIndex = letterIndex(ch); | ||
| if (trieNodeState[i].children[letterIndex] == null) break; | ||
| trieNodeStateNext[i] = trieNodeState[i].children[letterIndex]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This allows duplicate usage of words, as the problem allows.
ErdemT09
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Such string algorithms are something that we have not worked on in this repository. This is a good example for further algorithms we might examine such suffix arrays and trees.
Resolves: #220
A word square matrix is naturally a symmetric matrix.
It means when we try the
candidatewords starting from the top row to the bottom row, the symmetric order will occur eventually, like in the above picture.Therefore, we can interpret this situation as a
constraint, and aconstraintis nothing but a guide to pruning a solution tree.As this question asks for
all possible solutionsto construct a word square and there occurs aconstraintthat helps us prune the tree, a kind ofbacktracking techniqueinevitably comes to mind.In each insertion of the candidate words into the matrix, a
prefix(which is the constraint at the same time) is built naturally.Like in the picture:
ballinto the matrix as the first candidate, we are obliged to insert a word starting with the prefixainto the second row.leinto the third row.We could use a HashMap kind of data structure to store and retrieve the list of the words starting with the prefix needed.
We would use the prefix as a key, and the list of the words as the value.
But when we mention
prefixandre(trie)ve, a Trie (prefix tree) data structure might be the perfect match.The solution in the code is the fastest one on LeetCode. I just modularized and cleaned it to make it more readable.
Although the code is quite brilliant, there are some parts that disturb me.
For example, we need to fill an array with the same prefix tree to prune the root after each step. Sure, it helps to fasten the search on the tree, but there might be a leaner way about memory.
But for now, the solution is quite fine, according to me. When we turn back for this question to refactor it, we can think about making it leaner.