java 291. Word Pattern II(#)。java

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 291. Word Pattern II(#)。java相关的知识,希望对你有一定的参考价值。

/*
The idea might not be so different, but I tried to optimize the solution as much as I could. In concrete:

Instead of using HashMap, I use a String array to store the character --> String mapping
Instead of trying all combinations, I only try necessary/possible ones.
https://discuss.leetcode.com/topic/36076/java-hashset-backtracking-2ms-beats-100
*/
public boolean wordPatternMatch(String pattern, String str) {
    String[] map = new String[26]; // mapping of characters 'a' - 'z'
    HashSet<String> set = new HashSet<>(); // mapped result of 'a' - 'z'
    return wordPatternMatch(pattern, str, map, set, 0, str.length()-1, 0, pattern.length()-1);
}
private boolean wordPatternMatch(String pattern, String str, String[] map, HashSet<String> set, int start, int end, int startP, int endP) {
	if(startP==endP+1 && start==end+1) return true; // both pattern and str are exhausted
	if((startP>endP && start<=end) || (startP<endP && start>end)) return false; // either of pattern or str is exhausted

	char ch = pattern.charAt(startP);
	String matched = map[ch-'a'];
	if(matched!=null) { // ch is already mapped, then continue
		int count = matched.length();
		return start+count<=end+1 && matched.equals(str.substring(start, start+count)) // substring equals previously mapped string
				&& wordPatternMatch(pattern, str, map, set, start+matched.length(), end, startP+1, endP); // moving forward
	}
	else {
	    int endPoint = end;
	    for(int i=endP; i>startP; i--) {
	        endPoint -= map[pattern.charAt(i)-'a']==null ? 1 : map[pattern.charAt(i)-'a'].length();
	    }
		for(int i=start; i<=endPoint; i++) { // try every possible mapping, from 1 character to the end
			matched = str.substring(start, i+1);
			if(set.contains(matched)) continue; // different pattern cannot map to same substring

			map[ch-'a'] = matched; // move forward, add corresponding mapping and set content
			set.add(matched);

			if(wordPatternMatch(pattern, str, map, set, i+1, end, startP+1, endP)) return true;

			else { // backtracking, remove corresponding mapping and set content
				map[ch-'a'] = null;
				set.remove(matched);
			}
		}
	}
	return false; // exhausted
}
public class Solution {
    private boolean backtracking(String pattern, String str, int pIdx, int sIdx, Map<Character, String> map, Set<String> set) {
        if (pattern.length() == pIdx && str.length() == sIdx) return true;
        if (pattern.length() == pIdx || str.length() == sIdx) return false;
        
        char c = pattern.charAt(pIdx);
        if (map.containsKey(c)) {
            String s = map.get(c);
            if (!str.startsWith(s, sIdx)) {
                return false;
            }
            return backtracking(pattern, str, pIdx + 1, sIdx + s.length(), map, set);
        } 
        for (int i = sIdx; i < str.length(); i++) {
            String candidate = str.substring(sIdx, i + 1);
            
            if (set.contains(candidate)) continue;
            map.put(c, candidate);
            set.add(candidate);
            if (backtracking(pattern, str, pIdx + 1, i + 1, map, set)) {
                return true;
            }
            map.remove(c);
            set.remove(candidate);
        }
        return false;
    }
    public boolean wordPatternMatch(String pattern, String str) {
        Map<Character, String> map = new HashMap<>();
        Set<String> set = new HashSet<>();
        return backtracking(pattern, str, 0, 0, map, set);
    }
}

以上是关于java 291. Word Pattern II(#)。java的主要内容,如果未能解决你的问题,请参考以下文章

java 291. Word Pattern II(#)。java

java 291. Word Pattern II(#)。java

java 291. Word Pattern II(#)。java

java 291. Word Pattern II(#)。java

291. Word Pattern II

291. Word Pattern II