634 · 单词矩阵

链接: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);
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值