Welcome to Subscribe On Youtube

Question

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

Given two strings s and t, return the number of distinct subsequences of s which equals t.

The test cases are generated so that the answer fits on a 32-bit signed integer.

 

Example 1:

Input: s = "rabbbit", t = "rabbit"
Output: 3
Explanation:
As shown below, there are 3 ways you can generate "rabbit" from s.
rabbbit
rabbbit
rabbbit

Example 2:

Input: s = "babgbag", t = "bag"
Output: 5
Explanation:
As shown below, there are 5 ways you can generate "bag" from s.
babgbag
babgbag
babgbag
babgbag
babgbag

 

Constraints:

  • 1 <= s.length, t.length <= 1000
  • s and t consist of English letters.

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

  • 
    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;
    
    	    }
    	}
    
    }
    
    ############
    
    class Solution {
        public int numDistinct(String s, String t) {
            int m = s.length(), n = t.length();
            int[][] dp = new int[m + 1][n + 1];
            for (int i = 0; i <= m; ++i) {
                dp[i][0] = 1;
            }
            for (int i = 1; i <= m; ++i) {
                for (int j = 1; j <= n; ++j) {
                    dp[i][j] += dp[i - 1][j];
                    if (s.charAt(i - 1) == t.charAt(j - 1)) {
                        dp[i][j] += dp[i - 1][j - 1];
                    }
                }
            }
            return dp[m][n];
        }
    }
    
  • // OJ: https://leetcode.com/problems/distinct-subsequences
    // Time: O(MN)
    // Space: O(N)
    class Solution {
    public:
        int numDistinct(string s, string t) {
            int M = s.size(), N = t.size();
            vector<long> dp(N + 1);
            dp[0] = 1;
            for (int i = 0; i < M; ++i) {
                for (int j = N - 1; j >= 0; --j) {
                    if (s[i] == t[j]) dp[j + 1] += dp[j];
                    if (dp[j + 1] > INT_MAX) dp[j + 1] = 0;
                }
            }
            return dp[N];
        }
    };
    
  • class Solution:
        def numDistinct(self, s: str, t: str) -> int:
            m, n = len(s), len(t)
            dp = [[0] * (n + 1) for _ in range(m + 1)]
            for i in range(m + 1):
                dp[i][0] = 1
            for i in range(1, m + 1):
                for j in range(1, n + 1):
                    dp[i][j] = dp[i - 1][j]
                    if s[i - 1] == t[j - 1]:
                        dp[i][j] += dp[i - 1][j - 1]
            return dp[m][n]
    
    ############
    
    class Solution(object):
      # space O(n^2)
      def _numDistinct(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: int
        """
        dp = [[0] * (len(t) + 1) for _ in range(0, len(s) + 1)]
    
        for i in range(0, len(s) + 1):
          dp[i][0] = 1
    
        for i in range(1, len(s) + 1):
          for j in range(1, len(t) + 1):
            dp[i][j] += dp[i - 1][j]
            if t[j - 1] == s[i - 1]:
              dp[i][j] += dp[i - 1][j - 1]
    
        return dp[-1][-1]
    
      def numDistinct(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: int
        """
        dp = [0] * (len(t) + 1)
        for i in range(1, len(s) + 1):
          pre = 1
          for j in range(1, len(t) + 1):
            tmp = dp[j]
            if t[j - 1] == s[i - 1]:
              dp[j] += pre
            pre = tmp
        return dp[-1]
    
    
  • func numDistinct(s string, t string) int {
    	m, n := len(s), len(t)
    	dp := make([][]int, m+1)
    	for i := 0; i <= m; i++ {
    		dp[i] = make([]int, n+1)
    		dp[i][0] = 1
    	}
    	for i := 1; i <= m; i++ {
    		for j := 1; j <= n; j++ {
    			dp[i][j] = dp[i-1][j]
    			if s[i-1] == t[j-1] {
    				dp[i][j] += dp[i-1][j-1]
    			}
    		}
    	}
    	return dp[m][n]
    }
    
    
  • function numDistinct(s: string, t: string): number {
        const m = s.length;
        const n = t.length;
        const dp: number[][] = new Array(m + 1)
            .fill(0)
            .map(() => new Array(n + 1).fill(0));
        for (let i = 0; i <= m; ++i) {
            dp[i][0] = 1;
        }
        for (let i = 1; i <= m; ++i) {
            for (let j = 1; j <= n; ++j) {
                dp[i][j] = dp[i - 1][j];
                if (s.charAt(i - 1) === t.charAt(j - 1)) {
                    dp[i][j] += dp[i - 1][j - 1];
                }
            }
        }
        return dp[m][n];
    }
    
    

All Problems

All Solutions