編集距離と復号化方法:動的な問題を解決するためのプログラミング

選択肢の魔法の武器の多くを解決するための動的プログラミングアルゴリズム。
:のように要約することができると考え以前の状態を決定するために値が現在の状態値。
したがって、主題のこのタイプでは、焦点は、現在の状態と状態のリンクを見つけること
特定の理論には、タイトルのペアに直接引っ張られ、またはされていません

編集距離

この質問はleetcodeに難しい質問です。
ここに画像を挿入説明
WORD1とWORD2は、ビューの視点からの接続を表示することが困難であるため、一見被験者は、開始することができないと感じるかもしれ。
そこで、我々は国家間のリンクを見つけるために、動的プログラミングを使用しようとした
私たちは、D [i]の[j]を聞かせてを表し前に最初の文字列のiビット第2ストリングの最初のjビット間の編集距離を。
D [9]〜[9は栗のために、例えば2 ] WORD1とWORD2間のストリング編集距離によって表され、我々はこれである必要。
その後、ここでの焦点は、どのように我々は、D [i]の[j]は、それを見つけるのですか?分析の後、更新する3つの方法があります。

  • I、J-1位の前に第2ストリングにビット列は、第j番目のビット列インサート(Dの編集距離[I] [J =前1] +1)
  • ビット列の前にI-1の第jビットの2番目の文字列に、最初のビット列のiが(ビット編集距離D [I-1] [Jを削除] +1)
  • J-1位の前に2番目の文字列へのビット列の前にI-1、その後、i番目のビット文字を置き換えます。もし最初のビットのI列のと交換することなく、同一のjビットの2番目の文字列の最初の文字(編集距離Dを[I-1] [J-1]);一方、同一ではない場合、交換する必要がある(編集距離D [I-1] [J-1] +1)

分析の後、それはあまり明確ではないでしょうか?
すなわち、我々はD [i]が[j]を、必要とし、唯一のD [i]は[J-1である ] + 1、D [I-1]〜[J] + 1、D [I-1] [J- 1](又はD [I-1] [J -1]) を選択し、最小ライン上を。
明らかに、D [0]〜[J] = J、D [i]が[0] = I( I i番目の文字を挿入するビット列ニーズからヌル文字列となる)
の反復を経てステップによってこのように、結果を得るために、すなわち、ステップことができます。コードは以下の通りであります:

class Solution:
    def minDistance(self, word1, word2):
        len1 = len(word1)
        len2 = len(word2)
        # 若两个串中有一个为0串,则返回另一个串的长度
        if len1*len2 == 0:       
            return len1 + len2
        dp = [[0]*(len2+1) for _ in range(len1+1)]
        for i in range(len1+1):
            dp[i][0] = i
        for j in range(len2+1):
            dp[0][j] = j
        for i in range(1, len1+1):
            for j in range(1, len2+1):
                # 分别对应三种情况
                tog = dp[i-1][j-1]
                rep_1 = dp[i-1][j] + 1
                rep_2 = dp[i][j-1] + 1
                if word1[i-1] != word2[j-1]:
                    tog += 1
                dp[i][j] = min(tog, rep_1, rep_2)
        return dp[len1][len2]

デコードする方法

この質問はleetcodeに中程度の問題です。
ここに画像を挿入説明
各要素法による暴力をした後、一つ一つが決定される-この質問は少し触れて見えます。しかし、(...他のヨーヨー場合、それらヶ月)、それは少し複雑で考える
しかし、今、私たちは秘密兵器、動的計画を持っています!
古いルールは、2つの状態の間の関係を探求します。

私たちは、Dを聞かせて[i]を表す文字列のi番目の文字の解読方法の前に合計。だから、更新D [i]は、次のような場合があります。

  • 当第ビットが「0」である:1最初のビットが「1」又は「2」である場合、I-1、最初の復号モードのiビット用ケースは、I-1及びi番目のビットの組み合わせ(単独ビット「0」)に復号することはできません。このとき、D [私] = D [I-2]; 2は、I-1の他の要素の最初のビットであれば、文字列が復号できない(この時点でIビット単独素子、及びNot Iで復号することができませんジョイントデコーディング-1サイト元素。この時間D [I] = 0で
  • 当第I-1ビットが '1' である:ここで、i番目のビット要素を復号することができる(D [I-1])単独、および関節I-1位置デコーダ要素(D [I-2] [I]したがってD。 = D [I-1] + D [I-2]
  • 当第I-1ビットが「2」である:1、「1」と「6」との間のi番目のビット要素、及び第二のケースは、独立して復号することができるように、共同で復号することができます。D [I] = D [I-1] + D [I-2]; 2、他の要素のi番目のビット要素であれば、なく、それを復号化する最初のi-1サイト元素ジョイントは、唯一独立して復号することができます。このとき、D [I] = D [I -1]

あなたは1.1 D [I] = D [I-2]があるだろう、なぜ不思議、最初のi-1要素のみi番目の要素が復号バインディングためであり、もしそうであれば、Iを有してもよいです-2、I-1の要素(もしあれば)結合要素は存在しません。

ハハ、ビット面倒なものの、しかし、我々は最終的にすべての状態がアウトに分析されている置きます。
さらに、プロセスは以降のみDを含む[I]、D [I-1]、D [I-2] 我々は動的に(よりむしろアレイDを維持)、これらの値を表すために3つの定数を使用できるように、これスペースを節約します。

class Solution:
    def numDecodings(self, s: str) -> int:
        if s[0] == "0":
            return 0
        curr, pre, tmp = 1, 1, 1
        len_s = len(s)
        for i in range(1, len_s):
        # temp表示D[i-1]
        # curr表示D[i]
        # pre 表示D[i-2]
            temp = curr   
            if s[i] == '0':
                if s[i-1] == '1' or s[i-1] == '2':
                    curr = pre
                else:
                    return 0
            elif s[i-1] == '1' or (s[i-1]=='2' and s[i] >= '1' and s[i] <='6'):
                curr += pre
            pre = temp
        return curr
公開された19元の記事 ウォンの賞賛1 ビュー710

おすすめ

転載: blog.csdn.net/weixin_43901558/article/details/104827120