• [LeetCode] 291. Word Pattern II 词语模式 II


    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.

    290. Word Pattern 的拓展,区别是这里的单词字符串没有空格了,不能按空格把单词直接拆分出来。

    可以用回溯法来判断每一种情况,用哈希表建立模式字符和单词之间的映射,还需要用变量p和r来记录当前递归到的模式字符和单词串的位置,在递归函数中,如果p和r分别等于模式字符串和单词字符串的长度,说明此时匹配成功结束了,返回ture,反之如果一个达到了而另一个没有,说明匹配失败了,返回false。

    解法:回溯Backtracking

    Python:

    # Time:  O(n * C(n - 1, c - 1)), n is length of str, c is unique count of pattern,
    #                                there are H(n - c, c - 1) = C(n - 1, c - 1) possible splits of string,
    #                                and each one costs O(n) to check if it matches the word pattern.
    # Space: O(n + c)
    
    class Solution(object):
        def wordPatternMatch(self, pattern, str):
            """
            :type pattern: str
            :type str: str
            :rtype: bool
            """
            w2p, p2w = {}, {}
            return self.match(pattern, str, 0, 0, w2p, p2w)
    
    
        def match(self, pattern, str, i, j, w2p, p2w):
            is_match = False
            if i == len(pattern) and j == len(str):
                is_match = True
            elif i < len(pattern) and j < len(str):
                p = pattern[i]
                if p in p2w:
                    w = p2w[p]
                    if w == str[j:j+len(w)]:  # Match pattern.
                        is_match = self.match(pattern, str, i + 1, j + len(w), w2p, p2w)
                    # Else return false.
                else:
                    for k in xrange(j, len(str)):  # Try any possible word
                        w = str[j:k+1]
                        if w not in w2p:
                            # Build mapping. Space: O(n + c)
                            w2p[w], p2w[p] = p, w;
                            is_match = self.match(pattern, str, i + 1, k + 1, w2p, p2w)
                            w2p.pop(w), p2w.pop(p);
                        if is_match:
                            break
            return is_match  

    C++:

    class Solution {
    public:
        bool wordPatternMatch(string pattern, string str) {
            unordered_map<char, string> m;
            return helper(pattern, 0, str, 0, m);
        }
        bool helper(string pattern, int p, string str, int r, unordered_map<char, string> &m) {
            if (p == pattern.size() && r == str.size()) return true;
            if (p == pattern.size() || r == str.size()) return false;
            char c = pattern[p];
            for (int i = r; i < str.size(); ++i) {
                string t = str.substr(r, i - r + 1);
                if (m.count(c) && m[c] == t) {
                    if (helper(pattern, p + 1, str, i + 1, m)) return true;
                } else if (!m.count(c)) {
                    bool b = false;
                    for (auto it : m) {
                        if (it.second == t) b = true;
                    } 
                    if (!b) {
                        m[c] = t;
                        if (helper(pattern, p + 1, str, i + 1, m)) return true;
                        m.erase(c);
                    }
                }
            }
            return false;
        }
    };  

    C++:

    class Solution {
    public:
        bool wordPatternMatch(string pattern, string str) {
            unordered_map<char, string> m;
            set<string> s;
            return helper(pattern, 0, str, 0, m, s);
        }
        bool helper(string pattern, int p, string str, int r, unordered_map<char, string> &m, set<string> &s) {
            if (p == pattern.size() && r == str.size()) return true;
            if (p == pattern.size() || r == str.size()) return false;
            char c = pattern[p];
            for (int i = r; i < str.size(); ++i) {
                string t = str.substr(r, i - r + 1);
                if (m.count(c) && m[c] == t) {
                    if (helper(pattern, p + 1, str, i + 1, m, s)) return true;
                } else if (!m.count(c)) {
                    if (s.count(t)) continue;
                    m[c] = t;
                    s.insert(t);
                    if (helper(pattern, p + 1, str, i + 1, m, s)) return true;
                    m.erase(c);
                    s.erase(t);
                }
            }
            return false;
        }
    };
    

      

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    GUI 之 JDialog弹窗
    GUI Swing 之 JFrame窗体
    GUI 键盘监听事件
    GUI 窗口监听事件
    GUI 鼠标监听事件,模拟画图工具
    shell编程
    Ubuntu20.04 Linux初识
    rlwrap的使用
    5个相见恨晚的Linux命令,每一个都非常实用
    Bash初识与常用命令
  • 原文地址:https://www.cnblogs.com/lightwindy/p/9736251.html
Copyright © 2020-2023  润新知