[LeetCode] 890. Find and Replace Pattern 查找和替换模式
You have a list of `words` and a `pattern`, and you want to know which words in `words` matches the pattern.
A word matches the pattern if there exists a permutation of letters p so that after replacing every letter x in the pattern with p(x), we get the desired word.
(Recall that a permutation of letters is a bijection from letters to letters: every letter maps to another letter, and no two letters map to the same letter.)
Return a list of the words in words that match the given pattern.
You may return the answer in any order.
Example 1:
Input: words = ["abc","deq","mee","aqq","dkd","ccc"], pattern = "abb"
Output: ["mee","aqq"]
Explanation: "mee" matches the pattern because there is a permutation {a -> m, b -> e, ...}.
"ccc" does not match the pattern because {a -> c, b -> c, ...} is not a permutation,
since a and b map to the same letter.
Note:
1 <= words.length <= 501 <= pattern.length = words[i].length <= 20
这道题给了我们一个字符串数组 words,还有一个 pattern 单词,问 words 数组中的单词是否满足 pattern 的模式,并给了一个例子。比如 pattern 是 abb 的话,表示后两个字母是相同的,比如 mee 和 aqq,那么一个很直接的想法就是建立每个单词 word 和 pattern 中每个字符之间的映射,比如 mee->abb 的话,就是 m->a, e->b,在建立映射之前要判断,若已经存在了该映射,且映射值不是当前 pattern 中的对应字符时,就是无法匹配的,比如 mm 和 ab,在第一次建立了 m->a 的映射,当遍历到第二个m的时候,发现m的映射已经存在,但不是b,就不能再建立 m->b 的映射,则表示无法匹配。分析到这里,你可能感觉没啥问题,但其实我们忽略一种情况,word 和 pattern 中的每个字符必须是一一对应的,任何一个方向的多对一都是不行了,比如 mn 和 aa,刚开始建立了 m->a 的映射,遍历到n的时候,发现没有n的映射,此时也不能建立 n->a 的映射,因为 pattern 中的a已经被占用了,所以还需要一个 HashMap 来建立反方向的映射,只有两个 HashMap 中都不存在的,才能建立映射,只要有一个已经存在了,直接 break 掉。在 for 循环结束后,看是否已经到达了 word 的末尾,没有提前 break 掉的话,就将 word 加入结果 res 中即可,参见代码如下:
解法一:
class Solution {
public:
vector<string> findAndReplacePattern(vector<string>& words, string pattern) {
vector<string> res;
for (string word : words) {
unordered_map<char, char> w2p, p2w;
int i = 0, n = word.size();
for (; i < n; ++i) {
if (w2p.count(word[i]) && w2p[word[i]] != pattern[i]) break;
w2p[word[i]] = pattern[i];
if (p2w.count(pattern[i]) && p2w[pattern[i]] != word[i]) break;
p2w[pattern[i]] = word[i];
}
if (i == n) res.push_back(word);
}
return res;
}
};
我们也可以不用 HashMap,改用两个长度为 26 的数组,因为这道题貌似默认都是小写字母,唯一麻烦一点的就是要把字母减去 'a' 来转为对应的坐标,还有一点跟上面解法不同的地方就是,字母是跟起坐标位置加1来建立映射(加1的原因是默认值是0,而当 i=0 时为了区分默认值,就要加1),因为两个字母都跟一个特定的值相等,其实也等价于这两个字母之间建立的映射(a->c, b->c => a->b)。整体思路还是没啥不同的,参见代码如下:
解法二:
class Solution {
public:
vector<string> findAndReplacePattern(vector<string>& words, string pattern) {
vector<string> res;
for (string word : words) {
vector<int> w(26), p(26);
int i = 0, n = word.size();
for (; i < n; ++i) {
if (w[word[i] - 'a'] != p[pattern[i] - 'a']) break;
w[word[i] - 'a'] = p[pattern[i] - 'a'] = i + 1;
}
if (i == n) res.push_back(word);
}
return res;
}
};
在论坛上又看到了一种解法,这种解法相当于把所有的单词都转为了一种特定的模式,具体来说,就是用一个 HashMap,建立每个字母跟其之前出现过的字母种类个数之前的映射,比如 mee->011,aqq->011,这样相同的模式映射的值是一样的,具体的做法是若当前字母没有出现过,则建立和当前 HashMap 中的映射个数之间的映射,是一种很巧妙的设计思路,只不过最后又给每个数字加上了 'a',转为了字母的 pattern,即 mee->abb,aqq->abb,参见代码如下:
解法三:
class Solution {
public:
vector<string> findAndReplacePattern(vector<string>& words, string pattern) {
vector<string> res;
for (string word : words) {
if (helper(word) == helper(pattern)) res.push_back(word);
}
return res;
}
string helper(string word) {
unordered_map<char, int> m;
for (char c : word) {
if (!m.count(c)) m[c] = m.size();
}
for (int i = 0; i < word.size(); ++i) word[i] = 'a' + m[word[i]];
return word;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/890
类似题目:
参考资料:
https://leetcode.com/problems/find-and-replace-pattern/
https://leetcode.com/problems/find-and-replace-pattern/discuss/161266/JAVA-3ms-Clear-Code
[LeetCode All in One 题目讲解汇总(持续更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)
[LeetCode] 890. Find and Replace Pattern 查找和替换模式的更多相关文章
- Leetcode 890. Find and Replace Pattern
把pattern映射到数字,也就是把pattern标准化. 比如abb和cdd如果都能标准化为011,那么就是同构的. class Solution: def findAndReplacePatter ...
- 890. Find and Replace Pattern - LeetCode
Question 890. Find and Replace Pattern Solution 题目大意:从字符串数组中找到类型匹配的如xyy,xxx 思路: 举例:words = ["ab ...
- LC 890. Find and Replace Pattern
You have a list of words and a pattern, and you want to know which words in words matches the patter ...
- 【LeetCode】890. Find and Replace Pattern 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典+set 单字典 日期 题目地址:https:/ ...
- [Swift]LeetCode890. 查找和替换模式 | Find and Replace Pattern
You have a list of words and a pattern, and you want to know which words in words matches the patter ...
- leetcode 890. 查找和替换模式 Python
用模式的每个字母去当做key对应单词列表的每个字母value, 如果放进dict之前检测到key已经存在,就检测Word[i][j]是否是和已经存在的value一致,不一致就代表不匹配,break检查 ...
- 890. Find and Replace Pattern找出匹配形式的单词
[抄题]: You have a list of words and a pattern, and you want to know which words in words matches the ...
- [LeetCode] Find And Replace in String 在字符串中查找和替换
To some string S, we will perform some replacement operations that replace groups of letters with ne ...
- 如何使用Replace Pioneer批量查找和替换并提取指定字符串
1 我们查看源代码之后获得的网页文件如下图所示,一般都是href="/p-286018571.html"我们只要能提取到所有的"/p-XXXXXXXX.html" ...
随机推荐
- git commit 提交失败
git commit -m 'xxx' 报错 报错信息 当前分支:master 远程分支:gitlib.xxx error: cannot spawn .git/hooks/commit-msg: N ...
- redis之主从同步
很多企业都没有使用到 Redis 的集群,但是至少都做了主从.有了主从,当 master 挂掉的时候,运维让从库过来接管,服务就可以继续,否则 master 需要经过数据恢复和重启的过程,这就可能会拖 ...
- Logstash:多个配置文件(conf)
Logstash:多个配置文件(conf) 对于多个配置的处理方法,有多个处理方法: 多个pipeline 一个pipleline处理多个配置文件 一个pipeline含有一个逻辑的数据流,它从inp ...
- Spring Boot 2.0 快速集成整合消息中间件 Kafka
欢迎关注个人微信公众号: 小哈学Java, 每日推送 Java 领域干货文章,关注即免费无套路附送 100G 海量学习.面试资源哟!! 个人网站: https://www.exception.site ...
- UWP 推荐 - 限时免费的RSS阅读器《RSS 追踪》登录 Windows 10
文/云之幻 前不久,博客作者 Bravo Yeung 写了一篇还算略受欢迎的关于 RSS 的文章 .Net开发者必知的技术类RSS订阅指南. RSS 现在用的人很少了,而且就算是我,也不过是在一周前才 ...
- 网格弹簧质点系统模拟(Spring-Mass System by Fast Method)附源码(转载)
转载: https://www.cnblogs.com/shushen/p/5311828.html 弹簧质点模型的求解方法包括显式欧拉积分和隐式欧拉积分等方法,其中显式欧拉积分求解快速,但积分步长 ...
- Linux文本文件——文本编辑器Vim
Linux文本文件——文本编辑器Vim 摘要:本文主要学习在Linux系统中使用Vim文本编辑器编辑文本. 什么是Vim Vim是一个基于文本界面的编辑工具,使用简单且功能强大.更重要的是,Vim是所 ...
- Python脚本1
[轮子]P123. 求最大约数,并鉴别是否为素数
- Java实现贪吃蛇游戏(含账号注册登录,排行榜功能)
这是我第一次工程实践的作业,选题很多,但我只对其中的游戏开发感兴趣,可游戏就两三个类型,最终还是选择了贪吃蛇.其实就贪吃蛇本身的代码实现还算是比较简单的,可是实践要求代码行达到一定数量,所以我就额外给 ...
- APS系统生产流转方式和批量算法研究
01.前言 在经济领域,生产型企业是经济的根基,有了生产型企业生产出的各种产品,才有物流.网上购物和金融融资等活动.对于生产型企业,其制造能力是其核心竞争力.如何提升制造能力一直是生产型企业面临的课题 ...