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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;
}
}