Leetcode: Word Squares && Summary: Another Important Implementation of Trie(Retrieve all the words with a given Prefix)

Given a set of words (without duplicates), find all word squares you can build from them.

A sequence of words forms a valid word square if the kth row and column read the exact same string, where 0 ≤ k < max(numRows, numColumns).

For example, the word sequence ["ball","area","lead","lady"] forms a word square because each word reads the same both horizontally and vertically.

b a l l
a r e a
l e a d
l a d y
Note:
There are at least 1 and at most 1000 words.
All words will have the exact same length.
Word length is at least 1 and at most 5.
Each word contains only lowercase English alphabet a-z.
Example 1:

Input:
["area","lead","wall","lady","ball"]

Output:
[
  [ "wall",
    "area",
    "lead",
    "lady"
  ],
  [ "ball",
    "area",
    "lead",
    "lady"
  ]
]

Explanation:
The output consists of two word squares. The order of output does not matter (just the order of words in each word square matters).
Example 2:

Input:
["abat","baba","atan","atal"]

Output:
[
  [ "baba",
    "abat",
    "baba",
    "atan"
  ],
  [ "baba",
    "abat",
    "baba",
    "atal"
  ]
]

Explanation:
The output consists of two word squares. The order of output does not matter (just the order of words in each word square matters).

Backtracking + Trie:    referred to https://discuss.leetcode.com/topic/63516/explained-my-java-solution-using-trie-126ms-16-16

A better approach is to check the validity of the word square while we build it.
Example: ["area","lead","wall","lady","ball"]
We know that the sequence contains 4 words because the length of each word is 4.
Every word can be the first word of the sequence, let‘s take "wall" for example.
Which word could be the second word? Must be a word start with "a" (therefore "area"), because it has to match the second letter of word "wall".
Which word could be the third word? Must be a word start with "le" (therefore "lead"), because it has to match the third letter of word "wall" and the third letter of word "area".
What about the last word? Must be a word start with "lad" (therefore "lady"). For the same reason above.

The picture below shows how the prefix are matched while building the sequence.

In order for this to work, we need to fast retrieve all the words with a given prefix. There could be 2 ways doing this:

  1. Using a hashtable, key is prefix, value is a list of words with that prefix.
  2. Trie, we store a list of words with the prefix on each trie node.

The implemented below uses Trie.

 1 public class Solution {
 2     public class TrieNode {
 3         TrieNode[] sons;
 4         List<String> startWith;
 5         public TrieNode() {
 6             this.sons = new TrieNode[26];
 7             this.startWith = new ArrayList();
 8         }
 9     }
10
11     public class Trie {
12         TrieNode root;
13         public Trie() {
14             this.root = new TrieNode();
15         }
16
17         public void insert(String word) {
18             char[] arr = word.toCharArray();
19             TrieNode node = root;
20             for (char c : arr) {
21                 if (node.sons[(int)(c-‘a‘)] == null) {
22                     node.sons[(int)(c-‘a‘)] = new TrieNode();
23                 }
24                 node.sons[(int)(c-‘a‘)].startWith.add(word);
25                 node = node.sons[(int)(c-‘a‘)];
26             }
27         }
28
29         public List<String> findByPrefix(String prefix) {
30             char[] pre = prefix.toCharArray();
31             TrieNode node = root;
32             for (char c : pre) {
33                 if (node.sons[(int)(c-‘a‘)] == null) {
34                     return new ArrayList<String>();
35                 }
36                 node = node.sons[(int)(c-‘a‘)];
37             }
38             return node.startWith;
39         }
40     }
41
42     public List<List<String>> wordSquares(String[] words) {
43         List<List<String>> res = new ArrayList<>();
44         if (words==null || words.length==0) return res;
45         int len = words[0].length();
46
47         //build trie
48         Trie trie = new Trie();
49         for (String word : words) {
50             trie.insert(word);
51         }
52
53         List<String> path = new ArrayList<String>();
54         for (String word : words) {
55             path.add(word);
56             helper(res, path, trie, len);
57             path.remove(path.size()-1);
58         }
59         return res;
60     }
61
62     public void helper(List<List<String>> res, List<String> path, Trie trie, int len) {
63         if (path.size() == len) {
64             res.add(new ArrayList<String>(path));
65             return;
66         }
67         int pos = path.size();
68         StringBuilder prefix = new StringBuilder();
69         for (String str : path) {
70             prefix.append(str.charAt(pos));
71         }
72         List<String> nextPossible = trie.findByPrefix(prefix.toString());
73         for (String str : nextPossible) {
74             path.add(str);
75             helper(res, path, trie, len);
76             path.remove(path.size()-1);
77         }
78     }
79 }
时间: 2024-10-29 19:07:32

Leetcode: Word Squares && Summary: Another Important Implementation of Trie(Retrieve all the words with a given Prefix)的相关文章

[LeetCode] Word Squares 单词平方

Given a set of words (without duplicates), find all word squares you can build from them. A sequence of words forms a valid word square if the kth row and column read the exact same string, where 0 ≤ k < max(numRows, numColumns). For example, the wor

Leetcode 425. Word Squares

Problem: Given a set of words (without duplicates), find all word squares you can build from them. A sequence of words forms a valid word square if the kth row and column read the exact same string, where 0 ≤ k < max(numRows, numColumns). For example

LeetCode &quot;Word Ladder&quot; - TRICKY

It is not as easy as I thought it to be, mostly because of time\space limitation. And actually that's the punch line of this problem My intuition was DFS. I got several failing attemption - all TLE or MLE. Since what we are supposed to find is 'short

[leetcode]Word Ladder II @ Python

[leetcode]Word Ladder II @ Python 原题地址:http://oj.leetcode.com/problems/word-ladder-ii/ 参考文献:http://blog.csdn.net/doc_sgl/article/details/13341405   http://chaoren.is-programmer.com/ 题意:给定start单词,end单词,以及一个dict字典.要求找出start到end的所有最短路径,路径上的每个单词都要出现在dict

[LeetCode] Word Search [37]

题目 Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be

LeetCode: Word Search [079]

[题目] Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not

LeetCode——Word Break

Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words. For example, given s = "leetcode", dict = ["leet", "code"]. Return true because

LeetCode: Word Break [139]

[题目] Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words. For example, given s = "leetcode", dict = ["leet", "code"]. Return true be

LeetCode: Word Break II [140]

[题目] Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word. Return all such possible sentences. For example, given s = "catsanddog", dict = ["cat", "cat