さまざまなサブシーケンス-動的計画法

トピックリンク

アイデア:
2つの文字列を右から左にトラバースします
。s[i]はs文字列の添え字iから末尾までの文字列を
表します。t[j]は添え字jからt文字列文字列の末尾までの文字を表します。

たとえば、「rara」と「ra」は
最初にaの末尾からトラバースされ
ます。i= 0、j = 0の場合、「rara」と「ra」が一致し、
「r」=「r」、一致、この時点で2つの状況があります。

  1. 「rara」の最初の「r」を考慮に入れると、「ra」の最初の「r」でキャンセルされます。「ara」の「a」の数を考慮するだけで、サブシーケンスNumber = dp [i + 1] [j + 1]
  2. 「rara」の最初の「r」が考慮されていない場合、それは「rar」の「ra」の数であり、サブシーケンスの数= dp [i + 1] [j]

これら2つのケースを合計すると、マッチング時のサブシーケンスの数が得られます。

一致しない場合は、上記の2番目のケースと直接等しくなります。

状態方程式:
s [i] = t [j]の場合、dp [i] [j] = dp [i + 1] [j + 1] + dp [i + 1] [j]
s [i] = Atの場合t [j]、dp [i] [j] = dp [i + 1] [j]

注:
j =文字列の長さの場合、t [j]はこの時点で空の文字列を表します。これは、任意の文字列のサブシーケンスです。

コード:

public int numDistinct(String s, String t) {
    
    
        int[][] dp = new int[s.length() + 1][t.length() + 1];
        for (int i = 0; i <= s.length(); i++) {
    
    
            dp[i][t.length()] = 1;
        }

        for (int i = s.length() - 1; i >= 0; i--) {
    
    
            char c = s.charAt(i);
            for (int j = t.length() - 1; j >= 0; j--) {
    
    
                if (c == t.charAt(j)) {
    
    
                    dp[i][j] = dp[i + 1][j + 1] + dp[i + 1][j];
                } else {
    
    
                    dp[i][j] = dp[i + 1][j];
                }
            }
        }

        return dp[0][0];
    }

おすすめ

転載: blog.csdn.net/qq_43665244/article/details/114925746