链接:LintCode 炼码 - ChatGPT!更高效的学习体验!
. - 力扣(LeetCode)
题解:
class Solution {
public:
struct Trie {
Trie() {
next.resize(26, nullptr);
end = false;
}
std::vector<Trie*> next;
bool end;
};
Trie* insert_trie(vector<string>& words) {
Trie* root = new (std::nothrow)Trie;
for (auto& word : words) {
Trie* cur = root;
for (int i = 0; i < word.size(); ++i) {
if (cur->next[word[i]-'a'] == nullptr) {
cur->next[word[i]-'a'] = new (std::nothrow) Trie;
}
cur = cur->next[word[i]-'a'];
}
cur->end = true;
}
return root;
}
vector<string> maxRectangle(vector<string>& words) {
if (words.size() <= 0) {
return {};
}
Trie* root = insert_trie(words);
if (!root) {
return {};
}
// 构建相同长度的表
int max_word_len = 0; //
std::unordered_map<int, std::unordered_set<string>> len2words;
for (auto& word : words) {
int len = word.size();
max_word_len = max(max_word_len, len);
len2words[len].insert(word);
}
// 回溯
// 最终结果,总共字符串的长度
int max_len = 0;
// 记录回溯路径
std::vector<string> path;
// 记录最终结果
std::vector<string> result;
for (auto& entry : len2words) {
path.clear();
dfs(root, entry.first, entry.second, path, result, max_len, max_word_len);
}
return result;
}
private:
void dfs(Trie* root, int len, unordered_set<string>& words,
std::vector<std::string>& path,
std::vector<std::string>& result,
int& max_len,
int max_word_len) {
// 如果当前字符的长度*宽度比最大的小,直接返回,剪枝
if (len * len <= max_len) {
return;
}
for (auto& word : words) {
// 把当前字符追加到路径 中
path.push_back(word);
// 判断已经追加的字符串是否是正确额度
auto valid = is_valid(path, root);
if (valid.first) {
// 获得字符串矩形的面积
int tmp_len = path[0].size() * path.size();
if (valid.second && tmp_len > max_len) {
// 记录最大面积
max_len = tmp_len;
std::vector<string> tmp(path);
result = std::move(tmp);
}
// 递归下一层
dfs(root, len, words, path, result, max_len, max_word_len);
}
// 回溯
path.pop_back();
}
}
std::pair<int, int> is_valid(std::vector<std::string>& path, Trie* root) {
int word_len = path[0].size();
int row_size = path.size();
bool allend = true;
/*for (auto& tmp : path) {
cout << tmp << " ";
}
cout << endl;*/
// 判断字符矩阵,按照列查看是否,字符串在字典树中
for (int i = 0; i < word_len; ++i) {
Trie* cur = root;
for (int j = 0; j < row_size; ++j) {
if (cur->next[path[j][i]-'a'] == nullptr) {
return std::pair<int, int>(false, false);
}
cur = cur->next[path[j][i]-'a'];
}
// 如果当前字符不是结尾
if (!cur->end) {
allend = false;
}
}
//cout << " ====" << endl;
return std::pair<int, int>(true , allend);
}
};