[LeetCode] Word Pattern II 词语模式之二
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
类似题目:
参考资料:
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 词语模式之二的更多相关文章
- [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 ...
- [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 ...
- [LeetCode] Word Ladder II 词语阶梯之二
Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from ...
- LeetCode 290. Word Pattern (词语模式)
Given a pattern and a string str, find if str follows the same pattern. Here follow means a full mat ...
- [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 ...
- [LeetCode] 126. Word Ladder II 词语阶梯之二
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...
- [LeetCode] Word Break II 拆分词句之二
Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each ...
- Leetcode: Word Pattern II
Given a pattern and a string str, find if str follows the same pattern. Here follow means a full mat ...
- [LeetCode] Word Pattern 词语模式
Given a pattern and a string str, find if str follows the same pattern. Examples: pattern = "ab ...
随机推荐
- 菜鸟浅析JAVA,.NET,C/C++的区别
前言 以前经常看一些文章说到JAVA,.NET的区别,有时候C++er也会过来 凑凑热闹,突然发现这几天手停不下来了,也想写一篇文章 来分析一下 JAVA,.NET,C/C++的优缺点以及他们之间谁“ ...
- Solr Facet 默认值
前言 今天在用Solr Facet遇到了默认值的问题,我用Facet.field查询发现数据总共100条,刚开始没有注意,发现少个别数据,但是用这几个个别的id查询又能查出来数据.才发现是Facet默 ...
- 自己动手,实现一种类似List<T>的数据结构(一)
前言 上一篇文章<Unity3D中常用的数据结构总结与分析>简单总结了一下小匹夫工作中经常遇到的一些数据结构.不过小匹夫一直有种观点,就是光说的热闹实际啥也不做真的没啥意思.光说不练假把式 ...
- 微信支付:H5吊起支付API,不显示“确认支付、输入密码”界面
使用公众号进行支付,官方开发帮助文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1 其业务流程如下: 按照业务流程进行开发 ...
- 探究负边距(negative margin)原理
W3C规范在介绍margin时有这样一句话: Negative values for margin properties are allowed, but there may be implement ...
- stm32新建工程详细步骤
记得好早以前为了建一个keil的工程折腾了好久,在这里写写基本的Keil工程创建方法,以防自己以后再忘记: 新建工程 保存工程 选择器件 在这边新建文件夹,然后就是添加程序代码到里面去了.其中一些文件 ...
- 使用PhantomJS实现网页截图服务
这是上半年遇到的一个小需求,想实现网页的抓取,并保存为图片.研究了不少工具,效果都不理想,不是显示太差了(Canvas.Html2Image.Cobra),就是性能不怎么样(如SWT的Brower). ...
- Connect to the DSP on C6A8168/DM8168/DM8148 using CCS
转自ti-wiki 这份wiki,我曾经就收藏过,但是没有加以重视,以至于绕了一大圈的ccs开发环境的配置,现在正式收藏于自己的博客中...总结良多啊 Connecting to DSP on C6 ...
- SpringMVC + Spring + MyBatis 整合 + Spring shrio + easyUI + 权限管理框架,带shrio session和shrio cache集群实现方案
工作之余先来写了一个不算规范的简单架子 基于spring mvc + spring + mybatis + Spring shrio 基于redis的集群方案 系统权限部分,分成多个机构,其中每个机构 ...
- JavaScript基本数据类型和引用数据类型
ECMAScript包含两种不同数据类型的值:基本类型值和引用类型值.基本类型值指的是简单的数据段,而引用类型值那些可能有多个值构成的对象. 在进行变量赋值时,解析器必须确定这个值是基本类型值还是引用 ...