​LeetCode刷题实战425:单词方块

简介: 算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !

今天和大家聊的问题叫做 单词方块,我们先来看题面:https://leetcode-cn.com/problems/word-squares/

31.jpg

32.jpg

示例

示例 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"
]
]
解释:
输出包含两个单词方块,输出的顺序不重要,只需要保证每个单词方块内的单词顺序正确即可。

解题

思路 :开始直接暴力dfs妥妥的超时。正确做法是利用前缀特性,即

如果我们知道结果中第一个单词,那么下一个单词前缀我们是知道的。

比如有[ball],我们知道单词方块是 4X4,换句话说每个单词长度都为4,其次下个单词是a字母开头的。

假如我们找到一个a开头长度为4单词,变成[ball, area],那么第三个单词的前缀是le长度为4单词,依次类推。

class Solution {
public:
    int limit;
    unordered_map<string,unordered_set<int>> mp;
    vector<vector<string>> wordSquares(vector<string>& words) {
        if(words.empty() or words[0].empty()){return {};}
        vector<vector<string>> res;
        limit=words[0].size();
        vector<int> cur;
        for(int i=0;i<words.size();++i){
            string prefix="";
            for(int j=0;j<words[i].size();++j){
                prefix+=words[i][j];
                mp[prefix].insert(i);
            }
        }
        for(int i=0;i<words.size();++i){
            cur.emplace_back(i);
            dfs(res,words,cur);
            cur.pop_back();
        }
        return res;
    }
    void dfs(vector<vector<string>>& res,vector<string>& words,vector<int>& cur){
        // for(int x:cur){
        // cout<<words[x]<<endl;
        // }cout<<"-----------------"<<endl;
        if(cur.size()>=limit){//加入结果数组
            vector<string> cur_res;
            for(int i=0;i<cur.size();++i){
                cur_res.emplace_back(words[cur[i]]);
            }
            res.emplace_back(move(cur_res));
            return;
        }
        string prefix="";//先算下一个单词需要满足的前缀
        for(int j=0;j<cur.size();++j){
            prefix+=words[cur[j]][cur.size()];
        }
        if(mp.count(prefix)){
            for(int i:mp[prefix]){
                cur.push_back(i);
                dfs(res,words,cur);
                cur.pop_back();
            }
        }
    }
};

好了,今天的文章就到这里,如果觉得有所收获,请顺手点个在看或者转发吧,你们的支持是我最大的动力 。

相关文章
|
3月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
4月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
121 2
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
35 1
|
3月前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
2月前
Leetcode(最后一个单词长度)
这篇文章介绍了两种解决LeetCode第58题的方法,即计算给定字符串中最后一个单词的长度,方法包括翻转字符串和逆向遍历统计。
22 0
|
2月前
【LeetCode 20】151.反转字符串里的单词
【LeetCode 20】151.反转字符串里的单词
19 0
|
4月前
|
算法
LeetCode第58题最后一个单词的长度
LeetCode第58题"最后一个单词的长度"的解题方法,通过从字符串末尾向前遍历并计数非空格字符,直接得出最后一个单词的长度。
LeetCode第58题最后一个单词的长度
|
4月前
|
算法 Python
【Leetcode刷题Python】 LeetCode 2038. 如果相邻两个颜色均相同则删除当前颜色
本文介绍了LeetCode 2038题的解法,题目要求在一个由'A'和'B'组成的字符串中,按照特定规则轮流删除颜色片段,判断Alice是否能够获胜,并提供了Python的实现代码。
55 3
|
4月前
|
Python
【Leetcode刷题Python】50. Pow(x, n)
本文介绍了LeetCode第50题"Pow(x, n)"的解法,题目要求实现计算x的n次幂的函数,文章提供了递归分治法的详细解析和Python实现代码。
28 1
|
4月前
|
Python
【Leetcode刷题Python】LeetCode 478. 在圆内随机生成点
本文介绍了LeetCode 478题的解法,题目要求在给定圆的半径和圆心位置的情况下实现在圆内均匀随机生成点的功能,并提供了Python的实现代码。
34 1