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. 在 Windows Phone 中,为 Grid 添加 Tilt 效果

    在 Windows Phone 中,Tilt 效果是比较经典的效果,我们可以很简单的为按钮等控件添加这样的效果(使用 Windows Phone Toolkit 的Tilt 效果),但是,如果我们想要 ...

  2. ASP.NET从MVC5升级到MVC6 RC2 总目录 - 发布在RC2Release之后

    序言 随着MVC6RC2的推出,MVC6的脚步越来越近了.但是在我们的手里,有大批量的MVC5的项目.如何将MVC5升级到MVC6,将是一个很大的课题.微软官方暂时没有一个升级指导,或者一个迁移工具, ...

  3. java中动态代理的实现

    动态代理的实现 使用的模式:代理模式. 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.类似租房的中介. 两种动态代理: (1)jdk动态代理,jdk动态代理是由Java内部的反射机制 ...

  4. golang bytes.Buffer Reset

    func t() { a := []'} buf := new(bytes.Buffer) buf.Write(a) b := buf.Bytes() fmt.Println(b) buf.Reset ...

  5. 隔天开启tomcat spring报错

    严重: Error configuring application listener of class org.springframework.web.context.ContextLoaderLis ...

  6. Python (一) 简介、安装

    一.简介 Python:是著名的"龟叔"Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言. 那么Python 究竟是来做什么的? 首 ...

  7. jQuery fsBanner 手风琴

    fsbanner是一款自定义功能丰富的响应式网站Banner手风琴特效jQuery插件.该手风琴特效兼容性很好,支持点击和鼠标滑过等触发事件,并且可添加标题或描述. 在线实例 默认 带标题 鼠标滑过 ...

  8. github源码学习之UIImage+YYWebImage

    UIImage+YYWebImage是YYWebImage(https://github.com/ibireme/YYWebImage)中的一个分类,这个分类封装了一些image常用的变化方法,非常值 ...

  9. iOS - 捕获应用程序崩溃日志

    作为一名iOS移动应用开发者,为了确保你的应用程序正确无误,在将应用程序提交到应用商店之前,你必定会进行大量的测试工作:而且在你测试的过程中应用程序运行的很好,但是在应用商店上线之后,还是有用户抱怨应 ...

  10. Swift3 - String 字符串、Array 数组、Dictionary 字典的使用

    Swift相关知识,本随笔为 字符串.数组.字典的简单使用,有理解.使用错误的地方望能指正. ///************************************************** ...