Question

Formatted question description: https://leetcode.ca/all/115.html

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.

Algorithm

	r a b b b i t
	1 1 1 1 1 1 1 1
r 0 1 1 1 1 1 1 1
a 0 0 1 1 1 1 1 1
b 0 0 0 1 2 3 3 3
b 0 0 0 0 1 3 3 3
i 0 0 0 0 0 0 3 3
t 0 0 0 0 0 0 0 3

dp[0][0] = 1; // T and S are both empty strings. dp[0][1 … S.length()-1] = 1; // T is an empty string, S has only one subsequence match. dp[1 … T.length()-1][0] = 0; // S is an empty string, T is not an empty string, and S has no subsequence matching. dp[i][j] = dp[i][j-1] + (T[i-1] == S[j-1]? dp[i-1][j-1]: 0)

Code

Java

public class Distinct_Subsequences {

	public class Solution_iteration {
	    public int numDistinct(String s, String t) {

	        if (s == null || t == null)     return 0;
	        if (s.length() < t.length())    return 0;

	        int TLength = t.length();
	        int SLength = s.length();

	        int[][] dp = new int[TLength + 1][SLength + 1];
	        dp[0][0] = 1;

	        for (int i = 1; i <= SLength; i++) {
	            dp[0][i] = 1;
	        }
	        for (int i = 1; i <= TLength; i++) {
	            dp[i][0] = 0;
	        }

	        for (int i = 1; i <= TLength; i++) {
	            for (int j = 1; j <= SLength; j++) {
	                if (t.charAt(i - 1) == s.charAt(j - 1)) {
	                    dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1];
	                } else {
	                    dp[i][j] = dp[i][j - 1];
	                }
	            }
	        }

	        return dp[TLength][SLength];
	    }
	}

	/*
	Last executed input:
	"aabdbaabeeadcbbdedacbbeecbabebaeeecaeabaedadcbdbcdaabebdadbbaeabdadeaabbabbecebbebcaddaacccebeaeedababedeacdeaaaeeaecbe"
	"bddabdcae"
	*/
	public class Solution_recursion {
	    public int numDistinct(String s, String t) {

	        if (s.length() == 0) {
	            return t.length() == 0 ? 1 : 0;
	        }

	        if (t.length() == 0) {
	            return s.length() >= 0 ? 1 : 0; // @note: t is empty, so delete all in s is one solution
	        }

	        if (s.length() < t.length()) {
	            return 0;
	        }

	        int sum = 0;

	        if (s.charAt(0) == t.charAt(0)) {
	            sum += numDistinct(s.substring(1), t.substring(1));
	        }

	        sum += numDistinct(s.substring(1), t); // @note: anyway, have to try this one: eg, s='aa' and t='a', result=2

	        return sum;

	    }
	}

}

All Problems

All Solutions