文章目录
- 1. 题目
- 2. 解题
1. 题目
给定一个单词集合 (没有重复),找出其中所有的 单词方块 。
一个单词序列形成了一个有效的单词方块的意思是指从第 k 行和第 k 列 (0 ≤ k < max(行数, 列数)) 来看都是相同的字符串。
例如,单词序列 ["ball","area","lead","lady"]
形成了一个单词方块,因为每个单词从水平方向看和从竖直方向看都是相同的。
b a l l
a r e a
l e a d
l a d y
注意:
单词个数大于等于 1 且不超过 500。
所有的单词长度都相同。
单词长度大于等于 1 且不超过 5。
每个单词只包含小写英文字母 a-z。示例 1:
输入:
["area","lead","wall","lady","ball"]
输出:
[[ "wall","area","lead","lady"],[ "ball","area","lead","lady"]
]
解释:
输出包含两个单词方块,输出的顺序不重要,
只需要保证每个单词方块内的单词顺序正确即可。 示例 2:
输入:
["abat","baba","atan","atal"]
输出:
[[ "baba","abat","baba","atan"],[ "baba","abat","baba","atal"]
]解释:
输出包含两个单词方块,输出的顺序不重要,
只需要保证每个单词方块内的单词顺序正确即可。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/word-squares
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2. 解题
类似题目:程序员面试金典 - 面试题 17.25. 单词矩阵(Trie树+DFS回溯,hard)
- trie 的每个节点记录经过该节点的单词下标
class trie
{
public:bool isEnd = false;trie* next[26] = {NULL};vector<int> wd;//经过该节点的单词下标void insert(string& s, int idx){trie *cur = this;for(int i = 0; i < s.size(); ++i){if(!cur->next[s[i]-'a'])cur->next[s[i]-'a'] = new trie();cur = cur->next[s[i]-'a'];cur->wd.push_back(idx);}cur->isEnd = true;}
};
class Solution {vector<vector<string>> ans;int n;
public:vector<vector<string>> wordSquares(vector<string>& words) {trie* t = new trie();for(int i = 0; i < words.size(); ++i)t->insert(words[i], i);n = words[0].size();vector<string> mat;for(auto& w : words){mat.push_back(w);//以每个单词为1第一行,开始查找dfs(words, t, mat, 1);mat.pop_back();}return ans;}void dfs(vector<string>& words, trie* t, vector<string>& mat, int len){if(len == n){ans.push_back(mat);return;}string nextprefix;//获取下一行的前缀for(int i = 0; i < len; ++i)nextprefix += mat[i][len];trie* cur = t;for(int i = 0; i < nextprefix.size(); ++i){ //在trie中检查前缀是否存在if(!cur->next[nextprefix[i]-'a']) return;cur = cur->next[nextprefix[i]-'a'];}for(int wd_idx : cur->wd){ //存在前缀,在当前节点的单词中加入下一个单词mat.push_back(words[wd_idx]);dfs(words, t, mat, len+1);mat.pop_back();}}
};
160 ms 16.9 MB
我的CSDN博客地址 https://michael.blog.csdn.net/
长按或扫码关注我的公众号(Michael阿明),一起加油、一起学习进步!