leetcode *面試題 16.18. 模式匹配(待研究)

【題目】*面試題 16.18. 模式匹配

你有兩個字符串,即pattern和value。 pattern字符串由字母"a"和"b"組成,用於描述字符串中的模式。例如,字符串"catcatgocatgo"匹配模式"aabab"(其中"cat"是"a",“go"是"b”),該字符串也匹配像"a"、"ab"和"b"這樣的模式。但需注意"a"和"b"不能同時表示相同的字符串。編寫一個方法判斷value字符串是否匹配pattern字符串。

示例 1:

輸入: pattern = "abba", value = "dogcatcatdog"
輸出: true

示例 2:

輸入: pattern = "abba", value = "dogcatcatfish"
輸出: false

示例 3:

輸入: pattern = "aaaa", value = "dogcatcatdog"
輸出: false

示例 4:

輸入: pattern = "abba", value = "dogdogdogdog"
輸出: true
解釋: "a"="dogdog",b="",反之也符合規則

提示:
0 <= len(pattern) <= 1000
0 <= len(value) <= 1000
你可以假設pattern只包含字母"a"和"b",value僅包含小寫字母。

【解題思路1】枚舉

  • 先判斷爲空的極端條件;
  • 然後開始記錄a和b的數量,以及第一個a和b的座標,根據座標可以很容易找到兩者不同長度時對應的字符串;
  • 然後優先判斷a和b的數量爲1的情況;
  • 最後開始整活,由二元一次方程可以構造a的長度和b長度的關係,所有隻要遍歷a的長度情況就行了。
class Solution {
    public boolean patternMatching(String pattern, String value) {
        int count_a = 0, count_b = 0;
        for (char ch: pattern.toCharArray()) {
            if (ch == 'a') {
                ++count_a;
            } else {
                ++count_b;
            }
        }
        if (count_a < count_b) {
            int temp = count_a;
            count_a = count_b;
            count_b = temp;
            char[] array = pattern.toCharArray();
            for (int i = 0; i < array.length; i++) {
                array[i] = array[i] == 'a' ? 'b' : 'a';
            }
            pattern = new String(array);
        }
        if (value.length() == 0) {
            return count_b == 0;
        }
        if (pattern.length() == 0) {
            return false;
        }
        for (int len_a = 0; count_a * len_a <= value.length(); ++len_a) {
            int rest = value.length() - count_a * len_a;
            if ((count_b == 0 && rest == 0) || (count_b != 0 && rest % count_b == 0)) {
                int len_b = (count_b == 0 ? 0 : rest / count_b);
                int pos = 0;
                boolean correct = true;
                String value_a = "", value_b = "";
                for (char ch: pattern.toCharArray()) {
                    if (ch == 'a') {
                        String sub = value.substring(pos, pos + len_a);
                        if (value_a.length() == 0) {
                            value_a = sub;
                        } else if (!value_a.equals(sub)) {
                            correct = false;
                            break;
                        }
                        pos += len_a;
                    } else {
                        String sub = value.substring(pos, pos + len_b);
                        if (value_b.length() == 0) {
                            value_b = sub;
                        } else if (!value_b.equals(sub)) {
                            correct = false;
                            break;
                        }
                        pos += len_b;
                    }
                }
                if (correct && !value_a.equals(value_b)) {
                    return true;
                }
            }
        }
        return false;
    }
}
class Solution {
    public boolean patternMatching(String pattern, String value) {
        int a = 0, b = 0;    //統計a與b的個數
        for(int i = 0; i < pattern.length(); ++i){
            if(pattern.charAt(i) == 'a') a++;
            else b++;
        }
        if(value.equals("")){//空串直接返回
            if(a*b == 0) return true;
            return false;//a與b對應的串不能同時爲空
        }
        if(pattern.equals("")) return false;
        if(b == pattern.length()) a = b;    //只有a或只有b,統一處理
        if(a == pattern.length()){
            if(value.length()%a != 0) return false;
            int c = value.length()/a;
            String s = value.substring(0, c);//平均按照長度c斷開匹配
            for(int i = 0; i < a; ++i){
                if(!s.equals(value.substring(c*i, c*(i + 1)))) return false;
            }
            return true;
        }
        List<List<Integer>> r = new ArrayList<>();//記錄所有整數解的a與b的串的長度
        for(int i = 0; i <= value.length(); ++i){
            int temp = value.length() - a*i;
            if(temp < 0) break;
            if(temp%b == 0){
                List<Integer> res = new ArrayList<>();
                res.add(i);
                res.add(temp/b);
                r.add(res);
            }
        }
        int i = pattern.indexOf('a'), j = pattern.indexOf('b');
        for(List<Integer> v : r){
            int m = v.get(0), n = v.get(1), sum = 0;    //用sum累計下標值
            String s1 = value.substring(i*n, i*n + m), s2 = value.substring(j*m, j*m + n);
            if(s1.equals(s2)) continue;    //a與b對應的串不能相等
            boolean flag = true;
            for(int k = 0; k < pattern.length(); ++k){
                String s = pattern.charAt(k) == 'a'? s1: s2;
                int p = pattern.charAt(k) == 'a'? m: n;
                if(!s.equals(value.substring(sum, sum + p))){
                    flag = false;
                    break;
                }
                sum += p;
            }
            if(flag) return true;   //只要存在一組解,就爲真
        }
        return false;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章