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
Example
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"]]
Notice
- 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
.
Input test data (one parameter per line)How to understand a testcase?
分析
要求找出所有的解,使得第k行和第K列是相同的。这一题可以使用递归+回溯的办法遍历所有的可能的解,但是在遍历的时候需要判断当前的string是否在words中,所以我们构造一个TrieTree来保存所有的word。然后开始遍历,每一次在grid中增加一个word后,需要根据当前的已经添加的word得到一个前缀,通过这个前缀在TrieTree中寻找所有满足条件的word,然后分别进行尝试。
Code
class Solution {
public:
/*
* @param words: a set of words without duplicates
* @return: all word squares
*/
struct TrieTree
{
bool c[26];
bool isEnd;
TrieTree* next[26];
TrieTree()
{
for (int i = 0; i < 26; i ++)
{
c[i] = false;
next[i] = NULL;
isEnd = false;
}
}
void insertWord(const string& s)
{
if (s.size() == 0)
{
isEnd = true;
return;
}
int index = s[0] - 'a';
c[index] = true;
if (!next[index])
next[index] = new TrieTree();
next[index]->insertWord(s.substr(1));
}
void findWords(const string& prefix, vector<string>& words, string word)
{
int len = word.size();
if (len < prefix.size())
{
int index = prefix[len] - 'a';
if (!c[index])
return;
word.push_back(prefix[len]);
next[index]->findWords(prefix, words, word);
return;
}
if (isEnd)
{
words.push_back(word);
return;
}
for (int i = 0; i < 26; i ++)
{
if (c[i])
{
word.push_back(i + 'a');
next[i]->findWords(prefix, words, word);
word.pop_back();
}
}
return;
}
};
vector<vector<string>> wordSquares(vector<string> &words) {
// write your code here
vector<vector<string>> res;
int len = words.size();
if (len == 0)
return res;
TrieTree root;
int wordLen = words[0].size();
for (int i = 0; i < len; i ++)
{
if (words[i].size() != wordLen)
return res;
root.insertWord(words[i]);
}
vector<string> grid;
findSquares(&root, grid, wordLen, res);
return res;
}
void findSquares(TrieTree* root, vector<string> grid, int wordLen, vector<vector<string>>& res)
{
if (grid.size() == wordLen)
{
res.push_back(grid);
return;
}
string prefix;
int row = grid.size();
for (int i = 0; i < row; i ++)
{
prefix += grid[i][row];
}
vector<string> words;
root->findWords(prefix, words, "");
for (int i = 0; i < words.size(); i ++)
{
grid.push_back(words[i]);
findSquares(root, grid, wordLen, res);
grid.pop_back();
}
return;
}
};
运行效率
Your submission beats 44.80% Submissions!