Given a string S and a string T, count the number of distinct subsequences of T in S. 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.
We define the computation structure to be C[i][j] indicating the number of solutions for S[0...i-1] and T[0...j-1]. i/j in C represents #chars in the substring. It's easier if we include 0 in the structure to accommodate the case when there's no chars(empty string) considered. In order to expand this structure, when updating C[i][j] we have two options:
public int foo(String S, String T) { //if C[i][j] i means # chars. so C[?][0] === 1 int m = S.length(), n = T.length(); int[][] C = new int[m+1][n+1]; for(int i=0;i<=m;i++) C[i][0] = 1; for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { C[i][j] = C[i-1][j]; if(S.charAt(i-1)==T.charAt(j-1)) C[i][j]+=C[i-1][j-1]; } } return C[m][n]; }
If you try to solve this by hand you'll quickly realize what you do is simply fill out a table. The rows are chars from S, and columns are chars from T. You update in row-wise fashion each time (the inner loop). For each cell you first drag what's directly above current cell (C[i][j]=C[i-1][j]). And if chars are same, you increment it by its top-left neighbor(C[i][j]+=C[i-1][j-1]). So all computation can be done with the storage of a vector instead of a table. There is one problem however, which is in 2nd case we need C[j-1] (when reduced to 1-d vector, i ignored) but C[j-1] might be updated before reaching C[j]. The workaround is to use a temporary var to hold its value:
public int foo(String S, String T) { int m = S.length(), n = T.length(); int[] C = new int[n+1]; C[0] = 1; for(int i=1;i<=m;i++) { int lastval=C[0]; for(int j=1;j<=n;j++) { int thisval = C[j]; if(S.charAt(i-1)==T.charAt(j-1)) C[j]+=lastval; lastval = thisval; } } return C[n]; }