-
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| /build/ | ||
| /.gradle/ | ||
| .build.gradle | ||
| .build.gradle | ||
| /.idea/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| package algorithms.curated170.hard; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.Arrays; | ||
| import java.util.List; | ||
|
|
||
| public class WordSquaresTrieBacktracking { | ||
| public static class Solution { | ||
| public final static int LETTER_a = 97; | ||
|
|
||
| public List<List<String>> wordSquares(String[] words) { | ||
| TrieNode root = buiildTrie(words); | ||
| int n = words[0].length(); | ||
| TrieNode[] trieNodeState = new TrieNode[n]; | ||
| Arrays.fill(trieNodeState, root); | ||
| List<List<String>> ans = new ArrayList<>(); | ||
| dfs(0, new char[n][n], ans, trieNodeState); | ||
| return ans; | ||
| } | ||
| void dfs(int rowIndex, char[][] matrix, List<List<String>> ans, TrieNode[] trieNodeState) { | ||
| if (rowIndex == matrix.length) { | ||
| ans.add(convertMatrixToList(matrix, rowIndex)); | ||
| return; | ||
| } | ||
| TrieNode[] trieNodeStateNext = new TrieNode[trieNodeState.length]; | ||
| for (String candidate : trieNodeState[rowIndex].list) { | ||
|
|
||
| if (isSymmetric(matrix, candidate, rowIndex, trieNodeState, trieNodeStateNext)){ | ||
| dfs(rowIndex + 1, matrix, ans, trieNodeStateNext); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private boolean isSymmetric(char[][] matrix, String candidate, int rowIndex, | ||
| TrieNode[] trieNodeState, TrieNode[] trieNodeStateNext) { | ||
|
|
||
| int i = rowIndex; | ||
| while (i < matrix.length) { | ||
| char ch = candidate.charAt(i); | ||
| matrix[rowIndex][i] = ch; | ||
| if (i > rowIndex) { | ||
| matrix[i][rowIndex] = ch; | ||
| int letterIndex = letterIndex(ch); | ||
| if (trieNodeState[i].children[letterIndex] == null) break; | ||
| trieNodeStateNext[i] = trieNodeState[i].children[letterIndex]; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This allows duplicate usage of words, as the problem allows. |
||
| } | ||
| i++; | ||
| } | ||
| return (i == matrix.length); | ||
| } | ||
|
|
||
| TrieNode buiildTrie(String[] words){ | ||
| TrieNode root = new TrieNode(); | ||
| for (String w : words) { | ||
| root.list.add(w); | ||
| TrieNode tn = root; | ||
| for (char ch : w.toCharArray()) { | ||
| int index = letterIndex(ch); | ||
| if (tn.children[index] == null){ | ||
| tn.children[index] = new TrieNode(); | ||
| } | ||
| tn = tn.children[index]; | ||
| tn.list.add(w); | ||
| } | ||
| } | ||
| return root; | ||
| } | ||
| private List<String> convertMatrixToList(char[][] matrix, int rowIndex) { | ||
| List<String> words = new ArrayList<>(rowIndex); | ||
| for (char[] ca : matrix) words.add(new String(ca)); | ||
| return words; | ||
| } | ||
|
|
||
|
|
||
| private int letterIndex(char ch) | ||
| { | ||
| return (ch - LETTER_a); | ||
| } | ||
|
|
||
| class TrieNode { | ||
| List<String> list; | ||
| TrieNode[] children; | ||
| TrieNode() { | ||
| list = new ArrayList<>(); | ||
| children = new TrieNode[26]; | ||
| } | ||
| } | ||
| } | ||
| public static void main(String[] args) { | ||
| Solution solution = new Solution(); | ||
| solution.wordSquares(new String[]{ "area","lead","wall","lady","ball"}); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
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.