115. Distinct Subsequences

来源:互联网 发布:乌鲁木齐乐知少儿英语 编辑:程序博客网 时间:2024/06/03 22:16

题目:

Given a string S and a string T, count the number of distinct subsequences of S which equals T.
A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, “ACE” is a subsequence of “ABCDE” while “AEC” is not).
Here is an example:
S = “rabbbit”, T = “rabbit”
Return 3.
找出T是S的子序列,找出S存在多少个不同子序列与T相等。

动态规划

  • 定义数组
int[][] DP=new int[sLength+1][tLength+1];

DP[i][j]表示S前i个字符与T前j个字符的Distinct Subsequences

  • 定义数组
    当T为null时,S都只有1个子序列可以转化为。
for(int i=0;i<sLength+1;i++){    DP[i][0]=1;}
  • 状态转移方程
    当s.charAt(i-1)==t.charAt(j-1)时,有两种状态可以转化为DP[i][j]
    1.选择S的第i个字符,因为s.charAt(i-1)==t.charAt(j-1)则可以转化的个数为DP[i-1][j-1]。
    2.不选择S的第i个字符,这种情况与DP[i-1][j]相同。
    即DP[i][j]=DP[i-1][j-1]+DP[i-1][j];
    当s.charAt(i-1)!=t.charAt(j-1)时,这种情况与不选择不选择S的第i个字符相同。
    即DP[i][j]=DP[i-1][j];

  • 代码

public int numDistinct(String s, String t) {    int sLength=s.length();    int tLength=t.length();    int[][] DP=new int[sLength+1][tLength+1];    for(int i=0;i<sLength+1;i++){        DP[i][0]=1;    }    for(int i=1;i<=sLength;i++){        for(int j=1;j<=tLength;j++){            if(s.charAt(i-1)==t.charAt(j-1)){                DP[i][j]=DP[i-1][j-1]+DP[i-1][j];            }else{                DP[i][j]=DP[i-1][j];            }        }    }    return DP[sLength][tLength];}
  • 降维
    不难发现可以降为一维。
public int numDistinct(String s, String t) {            int sLength=s.length();            int tLength=t.length();            int[] DP=new int[tLength+1];            DP[0]=1;            for(int i=1;i<=sLength;i++) {                for (int j = Math.min(i, tLength); j >0; j--) {                    if(s.charAt(i-1)==t.charAt(j-1)){                        DP[j]+=DP[j-1];                    }                }            }            return DP[tLength];        }
原创粉丝点击