You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
1.9 KiB

2 years ago
package class45;
import java.util.HashSet;
public class Problem_0291_WordPatternII {
public static boolean wordPatternMatch(String pattern, String str) {
return match(str, pattern, 0, 0, new String[26], new HashSet<>());
}
// 题目有限制str和pattern其中的字符一定是a~z小写
// p[a] -> "abc"
// p[b] -> "fbf"
// 需要指代的表最多26长度
// String[] map -> new String[26]
// p[a] -> "abc" map[0] -> "abc"
// p[b] -> "fbf" map[1] -> "fbf";
// p[z] -> "kfk" map[25] -> "kfk"
// HashSet<String> set -> map中指代了哪些字符串
// str[si.......] 是不是符合 p[pi......]符合返回true不符合返回false
// 之前的决定由map和set告诉我不能冲突
public static boolean match(String s, String p, int si, int pi, String[] map, HashSet<String> set) {
if (pi == p.length() && si == s.length()) {
return true;
}
// str和pattern并没有都结束
if (pi == p.length() || si == s.length()) {
return false;
}
// str和pattern都没结束
char ch = p.charAt(pi);
String cur = map[ch - 'a'];
if (cur != null) { // 当前p[pi]已经指定过了!
return si + cur.length() <= s.length() // 不能越界!
&& cur.equals(s.substring(si, si + cur.length()))
&& match(s, p, si + cur.length(), pi + 1, map, set);
}
// p[pi]没指定!
int end = s.length();
// 剪枝!重要的剪枝!
for (int i = p.length() - 1; i > pi; i--) {
end -= map[p.charAt(i) - 'a'] == null ? 1 : map[p.charAt(i) - 'a'].length();
}
for (int i = si; i < end; i++) {
// 从si出发的所有前缀串全试
cur = s.substring(si, i + 1);
// 但是,只有这个前缀串,之前没占过别的坑!才能去尝试
if (!set.contains(cur)) {
set.add(cur);
map[ch - 'a'] = cur;
if (match(s, p, i + 1, pi + 1, map, set)) {
return true;
}
map[ch - 'a'] = null;
set.remove(cur);
}
}
return false;
}
}