Skip to content

Commit c498f17

Browse files
author
Longerhaha
authored
更新890_(查找和替换模式)Find and Repalce Pattern
更新890_(查找和替换模式)Find and Repalce Pattern解题描述到乔戈里leetcode每日一题库
1 parent 80399e1 commit c498f17

File tree

2 files changed

+99
-1
lines changed

2 files changed

+99
-1
lines changed

2018.11.30-leetcode890/1.md

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
## 890_(查找和替换模式)Find and Repalce Pattern
2+
## 1 问题描述、输入输出与样例
3+
### 1.1 问题描述
4+
你有一个单词列表 words 和一个模式 pattern,你想知道 words 中的哪些单词与模式匹配。<br>
5+
如果存在字母的排列 p ,使得将模式中的每个字母 x 替换为 p(x) 之后,我们就得到了所需的单词,那么单词与模式是匹配的。<br>
6+
(回想一下,字母的排列是从字母到字母的双射:每个字母映射到另一个字母,没有两个字母映射到同一个字母。)<br>
7+
返回 words 中与给定模式匹配的单词列表。<br>
8+
你可以按任何顺序返回答案。<br>
9+
__提示__:<br>
10+
1. 1 <= words.length <= 50<br>
11+
2. 1 <= pattern.length = words[i].length <= 20<br>
12+
### 1.2 输入与输出
13+
输入:<br>
14+
* vector<string>& words:给定的单词列表<br>
15+
* string pattern:模式单词<br>
16+
输出:<br>
17+
* vector<string>:与给定模式匹配的单词列表<br>
18+
19+
### 1.3 样例
20+
#### 1.3.1 样例1
21+
输入: <br>
22+
words = ["abc","deq","mee","aqq","dkd","ccc"], pattern = "abb"<br>
23+
24+
输出: <br>
25+
["mee","aqq"]<br>
26+
27+
解释:<br>
28+
"mee" 与模式匹配,因为存在排列 {a -> m, b -> e, ...}。<br>
29+
"ccc" 与模式不匹配,因为 {a -> c, b -> c, ...} 不是排列。
30+
因为 a 和 b 映射到同一个字母。<br>
31+
## 2 思路描述与代码
32+
### 2.1 思路描述(双字典方法)
33+
对每个属于单词列表words的单词word,使用dict1 记录 word 中的字符 word[i] 对 pattern 字符 pattern[i] 的映射<br>
34+
使用dict2 记录 pattern 中的字符 pattern[i] 对 word 字符 word[i] 的映射<br>
35+
```cpp
36+
for(word in words){
37+
初始化字典映射;
38+
for(word[i] in word){
39+
if(word[i] 未被映射)
40+
if(pattern[i] 未被映射) 双方记录映射关系;
41+
else 确认 pattern[i] 映射的对象是不是 word[i],如果不是则失败;
42+
if(word[i] 已被映射 且 映射对象不是 pattern[i]) 则失败;
43+
}
44+
如果成功,记录word;
45+
}
46+
```
47+
48+
### 2.2 代码
49+
```cpp
50+
vector<string> findAndReplacePattern(vector<string>& words, string pattern) {
51+
vector<string> ans;
52+
for( auto word : words ){
53+
// dict1 记录 word 中的字符对 pattern 字符的映射
54+
// dict2 记录 pattern 中的字符对 word 字符的映射
55+
vector<int> dict1(127, -1);
56+
vector<int> dict2(127, -1);
57+
int word_len = word.size();
58+
int fail = 0;
59+
for( int i = 0; i < word_len; i++ ){
60+
// 如果 word[i] 未被映射
61+
// (i) 如果 pattern[i] 未被映射,双方记录映射关系
62+
// (ii) 如果 pattern[i] 已被映射,确认 pattern[i] 映射的对象是不是 word[i],如果不是则失败
63+
if(dict1[word[i]] == -1){
64+
if(dict2[pattern[i]] == -1){
65+
dict1[word[i]] = pattern[i];
66+
dict2[pattern[i]] = word[i];
67+
}
68+
else if(dict2[pattern[i]] != word[i]){
69+
fail = 1;
70+
break ;
71+
}
72+
}
73+
// 如果 word[i] 已被映射 且 映射对象不是 pattern[i],则失败
74+
else if(dict1[word[i]] != -1 && dict1[word[i]] != pattern[i]){
75+
fail = 1;
76+
break ;
77+
}
78+
}
79+
//如果成功,记录word
80+
if(!fail) ans.push_back(word);
81+
}
82+
return ans;
83+
}
84+
```
85+
## 3 思考与拓展
86+
### 3.1 思考
87+
#### 3.1.1 其他方法
88+
无。
89+
#### 3.1.2 复杂度分析
90+
方法|空间复杂度|时间复杂度
91+
--- | --- | ---
92+
双字典方法|O(1)|O(kn),k为word的长度,n为words的数目
93+
#### 3.1.3 难点分析
94+
1. 如何记录二者的映射关系;
95+
2. 如何分辨映射存在一对多、多对一和多对多情况的出现。
96+
97+
### 3.1 扩展
98+
本题需要使用两个字典记录映射关系,不然可能导致一对多或者多对一情况。
99+

0 commit comments

Comments
 (0)