【DFS】LeetCode 291. 单词规律 II

题目链接

291. 单词规律 II

思路

定义一个全局 HashMap<Character, String> 来存储映射关系,key 为 pattern 的字符,value 为 str 的子串。
一开始,map 中没有任何映射关系。
把 pattern = "abab" 的第一个字符 'a' 和 str = "redblueredblue" 的第一个字符 "r" 当成映射关系,put 到 map 中。现在 map 中有一个映射关系 ('a', "r")。
现在,问题变成查找 "bab" 和 "edblueredblue" 的映射关系,其中,'a' 必须映射 "r"。
很明显,这是一个回溯问题。
如果回溯到最后 pattern 没有字符了,且 str 也没有字符了,说明刚好映射完毕,返回 true。
如果 pattern 字符用完了,str 还有剩下的字符,说明有可能一开始的映射关系就是不对的,因此重新调整初始的映射关系,例如调整为 'a' -> "re" ,继续回溯 "bab" 和 "dblueredblue"。
因为 "abab" 一个字符至少对应 "redblueredblue 的一个字符,"abab" 长度为 4,因此,'a' 最多对应 "redblueredb",留三个字符给 "aba"。
我们遍历回溯以下情况:
以 ('a' -> "r") 开始,查找 "bab" 和 "edblueredblue" 的映射关系;
以 ('a' -> "re") 开始,查找 "bab" 和 "dblueredblue" 的映射关系
以 ('a' -> "red") 开始,查找 "bab" 和 "blueredblue" 的映射关系
... ... ... ...
以 ('a' -> "redblueredb") 开始,查找 "bab" 和 "lue" 的映射关系
有可能中间某一个就直接返回 true,但是如果遍历完所有可能的开始,都没有返回 ture,说明也两个字符串不遵循相同的规律。

作者:K.L.B
链接:https://leetcode.cn/problems/word-pattern-ii/solutions/394077/291-dan-ci-gui-lu-ii-by-klb/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

代码

class Solution {
    private Map<Character, String> map = new HashMap<>();

    public boolean wordPatternMatch(String pattern, String s) {
        if(pattern.equals("")){
            return s.equals("");
        }

        Character c = pattern.charAt(0);
        // search from index 1
        for(int i = 1; i + pattern.length() - 1 <= s.length(); i++){
            String value = map.get(c);
            String subS = s.substring(0, i);

            if((value != null && subS.equals(value)) || (value == null  && !map.containsValue(subS))){
                map.put(c, subS);
                if(wordPatternMatch(pattern.substring(1), s.substring(i))){
                    return true;
                }else if(value == null){ // value == null means this entry is added just now
                    map.remove(c);
                }
            }
        }

        return false;
    }
}
posted @ 2023-02-27 14:08  Frodo1124  阅读(51)  评论(0编辑  收藏  举报