LeetCode-Word Pattern II

LiBlog發表於2016-09-03

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:

  1. pattern = "abab", str = "redblueredblue" should return true.
  2. pattern = "aaaa", str = "asdasdasdasd" should return true.
  3. pattern = "aabb", str = "xyzabcxzyabc" should return false.

Notes:
You may assume both pattern and str contains only lowercase letters.

Analysis:

Use recursion, similar to Word Search.

An important optimization:

https://discuss.leetcode.com/topic/36076/java-hashset-backtracking-2ms-beats-100/2

Solution:

public class Solution {
    public boolean wordPatternMatch(String pattern, String str) {
        HashSet<String> assigned = new HashSet<String>();
        String[] map = new String[26];
        Arrays.fill(map,"");
        return wordPatternMatchRecur(pattern,str,0,0,assigned,map);        
    }

    public boolean wordPatternMatchRecur(String pattern, String str, int pIndex, int sIndex, HashSet<String> assigned, String[] map){
        if (pIndex == pattern.length()){
            return sIndex==str.length();
        }

        if (sIndex==str.length()){
            return pIndex==pattern.length();
        }

        char code = pattern.charAt(pIndex);
        boolean matched = false;
        if (map[code-'a'].isEmpty()){
            // IMPORTANT OPTIMIZATION: the possible word for current code cannot go beyond a certain boundary, i.e., we need to leave enough length for the following pattern.
            int endPoint = str.length();
            for (int i=pattern.length()-1;i>pIndex;i--){
                endPoint -= (map[pattern.charAt(i)-'a'].isEmpty()) ? 1 : map[pattern.charAt(i)-'a'].length();
            }
            
            // Try to assign a word to current code.
            for (int i=sIndex;i<endPoint;i++){    
                String word = str.substring(sIndex,i+1);
                if (assigned.contains(word)) continue;
                
                map[code-'a'] = word;
                assigned.add(word);
                if (wordPatternMatchRecur(pattern,str,pIndex+1,i+1,assigned,map)) return true;
                assigned.remove(word);
                map[code-'a'] = "";
                
            }
            return false;
        } else {
            // Match code.word with the following str.
            String word = map[code-'a'];
            if (word.length() > str.length()-sIndex) return false;
            for (int i=0;i<word.length();i++)
                if (word.charAt(i) != str.charAt(sIndex+i)){
                    return false;
                }

            // If matched, move to next.
            matched = wordPatternMatchRecur(pattern,str,pIndex+1,sIndex+word.length(),assigned,map);
            return matched;
        }         
    }
}

 

相關文章