日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

面试题 16.18. Pattern Matching LCCI

發布時間:2024/5/7 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面试题 16.18. Pattern Matching LCCI 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Title

你有兩個字符串,即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僅包含小寫字母。

Solve

枚舉

設pattern的長度為lp,value的長度為lv,需要給字母a和b分配不同的字符串值(可以是空字符串),使得將pattern中的字母替換成對應的字符后,結果與value相同。

在分配字符串之前,可以先分配字符串的長度,然后只要將value按照pattern中出現字母的順序劃分成lp個子串,并判斷其中a對應的子串是否相同,以及b對應的子串是否相同即可。

具體說,假設pattern中出現了ca個a以及lp-ca個b,并且a和b對應字符串的長度分別為la-lb,那么必須滿足:ca*la+(lp-ca)*lb=lv

其中ca是已知的常量,la和lb是未知數。這是一個二元一次方程,可能無解、有唯一解或者無數解。

然而我們需要的僅僅是自然數解,也就是la和lb都大于等于0的解,因此我們可以直接枚舉la的值,它必須是[0, lv/ca]之間的自然數,在枚舉la之后,我們將其帶入等式并解出lb,如果lb是整數,我們就枚舉了一組a和b的可能長度。

在枚舉了長度之后,我們就可以根據 pattern 來將value 劃分成 lp 個子串。具體地,我們遍歷 pattern,并用一個指針pos 來幫助我們進行劃分。當我們遍歷到一個 a 時,我們取出從 pos 開始,長度為 la 的子串。如果這是我們第一次遇到字母 a,我們就得到了 a 應該對應的子串;否則,我們將取出的子串與 a 應該對應的子串進行比較,如果不相同,說明模式匹配失敗。

同理,當我們遍歷到一個 b 時,我們取出從 pos 開始,長度為 lb 的子串,根據是否第一次遇到字母 b 來進行比較。在比較結束后,我們將 pos 向后移動,進行下一個字母的匹配。

在遍歷完成之后,如果匹配沒有失敗,我們還需要判斷一下 a 和 b 是否對應了不同的子串。只有它們對應的子串不同時,才是一種滿足題目要求的模式匹配。

細節

回到二元一次方程:ca*la+(lp-ca)*lb=lv,我們枚舉la,那么必須要求ca!=0,因為在ca=0的情況下,原方程如果有解,那么一定有無數解(因為la可以取任意值)。

因此如果ca=0,我們就必須枚舉lb,這無疑增加了編碼的復雜度,因為需要根據ca的值選擇對la或lb進行枚舉,失去了統一性,并且,如果lp-ca也為0,那么我們連lb都無法枚舉。

因為,我們必須梳理一下判斷的邏輯:

  • 如果pattern為空,那么只有在value也為空時,它們才能匹配;
  • 如果value為空:
    (1). 如果pattern也為空,就和第一條情況相同;
    (2). 如果pattern中只出現了一種字母,令該字母為空,另一沒有出現的字母為任意非空串;
    (3). 如果pattern中出現了兩種字,那么就無法匹配成功,因為這兩種字母都必須為空串,而題目描述中規定它們不能表示相同的字符串;
  • 如果pattern和value均為非空,那么我們需要枚舉pattern中出現的那個字母(如果兩個字母均出現,可以枚舉任意一個)對應的長度,使用上面提到的算法進行判斷。
  • 對于第三條,我們可以根據【對稱性】減少代碼的編寫復雜度:固定枚舉la,但如果ca<lp-ca,即a出現的次數少于b出現的次數,那么我們就將pattern中所有的a替換成b,b替換成a,這樣做就保證了a出現了至少一次,枚舉la就不會有任何問題,同時不會影響答案的正確性。

    這樣一來,我們就可以優化判斷的邏輯:

  • 首先保證pattern中a出現的次數不少于b出現的次數,如果不滿足,將a和b互相替換;
  • 如果value為空,那么要求pattern也為空或者只出現字母a,這兩種情況均等同于lp-ca=0,其余情況下,都無法匹配成功;
  • 如果 pattern 為空且 value 不為空,那么無法匹配成功;
  • 如果 pattern 和 value 均非空,我們就可以枚舉 la 并使用上面提到的算法進行判斷。
  • Code

    class Solution:def patternMatching(self, pattern: str, value: str) -> bool:countA = sum(1 for c in pattern if c == 'a')countB = len(pattern) - countAif countA < countB:countA, countB = countB, countApattern = "".join('a' if c == 'b' else 'b' for c in pattern)if not value:return countB == 0if not pattern:return Falsefor lenA in range(len(value) // countA + 1):rest = len(value) - countA * lenAif (countB == 0 and rest == 0) or (countB != 0 and rest % countB == 0):lenB = 0 if countB == 0 else rest // countBpos, correct = 0, TruevalueA, valueB = None, Nonefor c in pattern:if c == 'a':sub = value[pos: pos + lenA]if not valueA:valueA = subelif valueA != sub:correct = Falsebreakpos += lenAelse:sub = value[pos: pos + lenB]if not valueB:valueB = subelif valueB != sub:correct = Falsebreakpos += lenBif correct and valueA != valueB:return Truereturn False

    復雜度分析

    時間復雜度:O(lv2?),其中 lp 和 lv 分別是 pattern 和 value 的長度。由于 la 必須是 [0, lv/ca] 中的自然數,并且 1/2lp<=ca<=lp,因此方程解的個數為 O(lv/lp)。對于每一組解,我們需要 O(lp+lv) 的時間來進行判斷,因此總時間復雜度為 O((lp+lv)lv/lp)。根據大 O 表示法的定義(漸進上界),可以看成 O(lv2)

    空間復雜度:O(lv)。我們需要存儲 a 和 b 對應的子串,它們的長度之和不會超過 lv

    總結

    以上是生活随笔為你收集整理的面试题 16.18. Pattern Matching LCCI的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。