Given a pattern and a string str, find if strfollows the same pattern.

Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty substring in str.

Example 1:

Input: pattern = "abab", str = "redblueredblue"
Output: true

Example 2:

Input: pattern = pattern = "aaaa", str = "asdasdasdasd"
Output: true

Example 3:

Input: pattern = "aabb", str = "xyzabcxzyabc"
Output: false

Notes:
You may assume both pattern and str contains only lowercase letters.

这道题是之前那道 Word Pattern 的拓展,之前那道题词语之间都有空格隔开,这样可以一个单词一个单词的读入,然后来判断是否符合给定的特征,而这道题没有空格了,那么难度就大大的增加了,因为我们不知道对应的单词是什么,所以得自行分开,可以用回溯法来生成每一种情况来判断,这里还是需要用 HashMap 来建立模式字符和单词之间的映射,还需要用变量p和r来记录当前递归到的模式字符和单词串的位置,在递归函数中,如果p和r分别等于模式字符串和单词字符串的长度,说明此时匹配成功结束了,返回 ture,反之如果一个达到了而另一个没有,说明匹配失败了,返回 false。如果都不满足上述条件的话,取出当前位置的模式字符,然后从单词串的r位置开始往后遍历,每次取出一个单词,如果模式字符已经存在 HashMap 中,而且对应的单词和取出的单词也相等,那么再次调用递归函数在下一个位置,如果返回 true,那么就返回 true。反之如果该模式字符不在 HashMap 中,要看有没有别的模式字符已经映射了当前取出的单词,如果没有的话,建立新的映射,并且调用递归函数,注意如果递归函数返回 false 了,要在 HashMap 中删去这个映射,参见代码如下:

解法一:

class Solution {
public:
bool wordPatternMatch(string pattern, string str) {
unordered_map<char, string> m;
return helper(pattern, , str, , m);
}
bool helper(string pattern, int p, string str, int r, unordered_map<char, string> &m) {
if (p == pattern.size() && r == str.size()) return true;
if (p == pattern.size() || r == str.size()) return false;
char c = pattern[p];
for (int i = r; i < str.size(); ++i) {
string t = str.substr(r, i - r + );
if (m.count(c) && m[c] == t) {
if (helper(pattern, p + , str, i + , m)) return true;
} else if (!m.count(c)) {
bool b = false;
for (auto it : m) {
if (it.second == t) b = true;
}
if (!b) {
m[c] = t;
if (helper(pattern, p + , str, i + , m)) return true;
m.erase(c);
}
}
}
return false;
}
};

下面这种方法和上面那种方法很类似,不同点在于使用了 set,而使用其的原因也是为了记录所有和模式字符建立过映射的单词,这样就不用每次遍历 HashMap 了,只要在 set 中查找取出的单词是否存在,如果存在了则跳过后面的处理,反之则进行和上面相同的处理,注意还要在 set 中插入新的单词,最后也要同时删除掉,参见代码如下:

解法二:

class Solution {
public:
bool wordPatternMatch(string pattern, string str) {
unordered_map<char, string> m;
unordered_set<string> st;
return helper(pattern, , str, , m, st);
}
bool helper(string pattern, int p, string str, int r, unordered_map<char, string> &m, unordered_set<string> &st) {
if (p == pattern.size() && r == str.size()) return true;
if (p == pattern.size() || r == str.size()) return false;
char c = pattern[p];
for (int i = r; i < str.size(); ++i) {
string t = str.substr(r, i - r + );
if (m.count(c) && m[c] == t) {
if (helper(pattern, p + , str, i + , m, st)) return true;
} else if (!m.count(c)) {
if (st.count(t)) continue;
m[c] = t;
st.insert(t);
if (helper(pattern, p + , str, i + , m, st)) return true;
m.erase(c);
st.erase(t);
}
}
return false;
}
};

再来看一种不写 helper 函数的解法,可以调用自身,思路和上面的方法完全相同,参见代码如下:

解法三:

class Solution {
public:
bool wordPatternMatch(string pattern, string str) {
if (pattern.empty()) return str.empty();
if (m.count(pattern[])) {
string t = m[pattern[]];
if (t.size() > str.size() || str.substr(, t.size()) != t) return false;
if (wordPatternMatch(pattern.substr(), str.substr(t.size()))) return true;
} else {
for (int i = ; i <= str.size(); ++i) {
if (st.count(str.substr(, i))) continue;
m[pattern[]] = str.substr(, i);
st.insert(str.substr(, i));
if (wordPatternMatch(pattern.substr(), str.substr(i))) return true;
m.erase(pattern[]);
st.erase(str.substr(, i));
}
}
return false;
}
unordered_map<char, string> m;
unordered_set<string> st;
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/291

类似题目:

Word Pattern

参考资料:

https://leetcode.com/problems/word-pattern-ii/

https://leetcode.com/problems/word-pattern-ii/discuss/73721/My-simplified-java-version

https://leetcode.com/problems/word-pattern-ii/discuss/73664/Share-my-Java-backtracking-solution

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Word Pattern II 词语模式之二的更多相关文章

  1. [LeetCode] 291. Word Pattern II 词语模式 II

    Given a pattern and a string str, find if str follows the same pattern. Here follow means a full mat ...

  2. [LeetCode] Word Search II 词语搜索之二

    Given a 2D board and a list of words from the dictionary, find all words in the board. Each word mus ...

  3. [LeetCode] Word Ladder II 词语阶梯之二

    Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from ...

  4. LeetCode 290. Word Pattern (词语模式)

    Given a pattern and a string str, find if str follows the same pattern. Here follow means a full mat ...

  5. [LeetCode] 212. Word Search II 词语搜索之二

    Given a 2D board and a list of words from the dictionary, find all words in the board. Each word mus ...

  6. [LeetCode] 126. Word Ladder II 词语阶梯之二

    Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...

  7. [LeetCode] Word Break II 拆分词句之二

    Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each ...

  8. Leetcode: Word Pattern II

    Given a pattern and a string str, find if str follows the same pattern. Here follow means a full mat ...

  9. [LeetCode] Word Pattern 词语模式

    Given a pattern and a string str, find if str follows the same pattern. Examples: pattern = "ab ...

随机推荐

  1. XLT架构图(自己 画的)

  2. HTML5 网络拓扑图性能优化

    HTML5 中的 Canvas 对文本的渲染(fillText,strokeText)性能都不太好,比如设置字体(font).文本旋转(rotation),如果绘制较多的文本时,一些交互操作会手动很大 ...

  3. 实现跨浏览器html5表单验证

    div:nth-of-type(odd){ float: left; clear: left; } .origin-effect > div:nth-of-type(even){ float: ...

  4. iOS 原生HTTP POST请求上传图片

    今天项目里做一个上传图片等个人信息的时候,使用了第三方AFNetworking - (AFHTTPRequestOperation *)POST:(NSString *)URLString param ...

  5. EntityFramework中的DbContext使用疑点说明

    1.DbContext怎么在Asp.mvc中使用? public class Repository { //实例化EF容器:有弊端.一个线程里可能会创建多个DbContext //DbContext ...

  6. [Oracle] Bulk Insert Data

    命名空间:Oracle.DataAccess.Client 组件:Oracle.DataAccess.dll(2.112.1.0) ODP.NET 版本:ODP.NET for .NET Framew ...

  7. C#遐想/瞎想

    泛型约束更强大.比如支持有参构造函数.枚举.委托: void Foo<T>() where T : new(string, int), enum, delegate 空值判断符允许对属性/ ...

  8. 【无私分享:ASP.NET CORE 项目实战(第八章)】读取配置文件(二) 读取自定义配置文件

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 我们在 读取配置文件(一) appsettings.json 中介绍了,如何读取appsettings.json. 但随之产生 ...

  9. how to use panda

    0.Introduce pandas.read_csv(filepath_or_buffer,sep=', ', dialect=None, compression='infer', doublequ ...

  10. Mysql增加、删除和修改列属性和约束,和一些有用的查询语句

    最近在整理关于MySql的东西,把一些需要记录的东西写下来,以便以后查询和浏览,以下是一些操作技巧.添加表字段alter table` 表名称` add transactor varchar(10) ...