无空间优化版本:

    /**
     * 
     * @param S string字符串 
     * @param T string字符串 
     * @return int整型
         返回 S 的子序列中 == T 的不同子序列的个数!
         即返回 能够把 S 转换为  T 的所有办法! 
       // f(i,j) 代表 S[0,i-1] 中 ==  T[0,j-1] 的子串个数!
       // 状态转移 f(i,j) = S[i-1] == T[j-1] ? f(i-1,j-1) + f(i-1,j) : f(i-1,j); 
     */
    public int numDistinct (String S, String T) {
       if(T.length() > S.length()) return 0;
       
        int m = S.length();
        int n = T.length();
        
        int[][] dp = new int[m+1][n+1]; 
        // 空串的子串和空串匹配存在唯一一个!
        dp[0][0] = 1;
        
        // 当 T 为空串时,只存无论 S多长,都只有一个子串空串!
        for(int i = 1; i <= m ; i++){
            dp[i][0] = 1;
        }
        
        // 当 T .length > S.length S中不可能存在子串 == T
        for(int i = 1; i <= n; i++){
            dp[0][i] = 0;
        }
        
        for(int i = 1; i <= m; i++){
            for(int j = 1; j <= n; j++){
              
                if(S.charAt(i-1) == T.charAt(j-1)){
                       // S的第i个字符与T的第j个字符相同
                    dp[i][j] = dp[i-1][j] + dp[i-1][j-1];
                }else {
                      // S的第i个字符与T的第j个字符不相同
                     // 从S的前i-1个字符中找子串,使子串与T的前j个字符相同
                    dp[i][j] = dp[i-1][j];
                }
            }
        }
        return dp[m][n];
    }

空间优化版本 :

    public int numDistinct (String S, String T) {
       if(T.length() > S.length()) return 0;
        int m = S.length();
        int n = T.length();
        
        int[] dp = new int[n+1]; 
        // 空串的子串和空串匹配存在唯一一个!
        dp[0] = 1;
        
        // 当 T .length > S.length S中不可能存在子串 == T
        for(int i = 1; i <= n; i++){
            dp[i] = 0;
        }
        /*
            一维数组的话,求当前位置的值 依赖于数组上一次结果的当前位置 于 当前位置的前一个位置所以采用 反向迭代!
        */
        for(int i = 1; i <= m; i++){
            for(int j = n; j > 0; j--){
                  if(S.charAt(i-1) == T.charAt(j-1))
                  dp[j] = dp[j-1] + dp[j];
            }
        }
        return dp[n];
    }