Word Pattern
Given a pattern and a string str, find if str follows the same pattern.
Examples:
pattern = "abba", str = "dog cat cat dog"
should return true.pattern = "abba", str = "dog cat cat fish"
should return false.pattern = "aaaa", str = "dog cat cat dog"
should return false.pattern = "abba", str = "dog dog dog dog"
should return false.Notes: patterncontains only lowercase alphabetical letters, and str contains words separated by a single space. Each word in str contains only lowercase alphabetical letters. Both pattern and str do not have leading or trailing spaces. Each letter in pattern must map to a word with length that is at least 1.
哈希表法
复杂度
时间 O(N) 空间 O(N)
思路
这题几乎和Isomorphic Strings一模一样,不同的就是之前是字母映射字母,现在是字母映射字符串而已。
代码
public class Solution {
public boolean wordPattern(String pattern, String str) {
Map<Character, String> map = new HashMap<Character, String>();
Set<String> set = new HashSet<String>();
String[] pieces = str.split(" ");
if(pieces.length != pattern.length()) return false;
int i = 0;
for(String s : pieces){
char p = pattern.charAt(i);
System.out.println(p);
// 如果该字符产生过映射
if(map.containsKey(p)){
// 且映射的字符串和当前字符串不一样
if(!s.equals(map.get(p))) return false;
} else {
// 如果该字符没有产生过映射
// 如果当前字符串已经被映射过了
if(set.contains(s)) return false;
// 否则新加一组映射
map.put(p, s);
set.add(s);
}
i++;
}
return true;
}
}
Word Pattern II
Given a pattern and a string str, find if str follows 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.
Examples:
pattern = "abab", str = "redblueredblue"
should return true.pattern = "aaaa", str = "asdasdasdasd"
should return true.pattern = "aabb", str = "xyzabcxzyabc"
should return false. Notes: You may assume both pattern and str contains only lowercase letters.
回溯法
复杂度
时间 O(N) 空间 O(N)
思路
因为目标字符串可以任意划分,所以我们不得不尝试所有可能性。这里通过深度优先搜索的回溯法,对于pattern中每个字母,在str中尝试所有的划分方式,如果划分出来的子串可以用这个字母映射,或者可以建立一个新的字母和字符串的映射关系,我们就继续递归判断下一个pattern中的字母。
代码
public class Solution {
Map<Character, String> map;
Set<String> set;
boolean res;
public boolean wordPatternMatch(String pattern, String str) {
// 和I中一样,Map用来记录字符和字符串的映射关系
map = new HashMap<Character, String>();
// Set用来记录哪些字符串被映射了,防止多对一映射
set = new HashSet<String>();
res = false;
// 递归回溯
helper(pattern, str, 0, 0);
return res;
}
public void helper(String pattern, String str, int i, int j){
// 如果pattern匹配完了而且str也正好匹配完了,说明有解
if(i == pattern.length() && j == str.length()){
res = true;
return;
}
// 如果某个匹配超界了,则结束递归
if(i >= pattern.length() || j >= str.length()){
return;
}
char c = pattern.charAt(i);
// 尝试从当前位置到结尾的所有划分方式
for(int cut = j + 1; cut <= str.length(); cut++){
// 拆出一个子串
String substr = str.substring(j, cut);
// 如果这个子串没有被映射过,而且当前pattern的字符也没有产生过映射
// 则新建一对映射,并且继续递归求解
if(!set.contains(substr) && !map.containsKey(c)){
map.put(c, substr);
set.add(substr);
helper(pattern, str, i + 1, cut);
map.remove(c);
set.remove(substr);
// 如果已经有映射了,但是是匹配的,也继续求解
} else if(map.containsKey(c) && map.get(c).equals(substr)){
helper(pattern, str, i + 1, cut);
}
// 否则跳过该子串,尝试下一种拆分
}
}
}