13.11 Distinct Subsequences

Link: https://oj.leetcode.com/problems/distinct-subsequences/

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.

My thought: I don't understand why output = 3 for the above example. For T, its subsequences = {r, ra, rab, rabb, rabbi, rabbit, a, ab, abb, abbi, ...} are all contained in S. 

Or does it mean how many complete T are contained in S?  Yes. 


My first thought: I think this is very similar to Unique Paths, Edit Distance, and Interleaving String

My code:

public class Solution {
    public int numDistinct(String S, String T) {
        if(S.length() < T.length()) return 0;
        int[][] f = new int[S.length()+1][T.length()+1];
        for(int j = 0; j < f[0].length; j++){
            f[0][j] = 0;
        }
        for(int i = 0; i < f.length; i++){
            f[i][0] = 1;
        }
        for(int i = 1; i < f.length; i++){
            for(int j = 1; j < f[0].length; j++){
                if(S.charAt(i-1) == T.charAt(j-1)){
                    f[i][j] = f[i-1][j-1];
                }
                else{
                    f[i][j] = f[i][j-1];
                }
            }
        }
        return f[S.length()][T.length()];
    }
}

This is wrong. When align S with T, S can have nulls, but T cannot. So f[i][j] can come from f[i-1][j-1], and f[i-1][j] (not f[i][j-1]). 

Approach I: 2D-DP

Time: O(mn), Space: O(mn)

public class Solution {
    public int numDistinct(String S, String T) {
        if(S.length() < T.length()) return 0;
        int[][] f = new int[S.length()+1][T.length()+1];
        for(int j = 0; j < f[0].length; j++){
            f[0][j] = 0;
        }
        for(int i = 0; i < f.length; i++){
            f[i][0] = 1;
        }
        for(int i = 1; i < f.length; i++){
            for(int j = 1; j < f[0].length; j++){
                f[i][j] = f[i-1][j];
                if(S.charAt(i-1) == T.charAt(j-1)){
                    f[i][j] += f[i-1][j-1];
                }
            }
        }
        return f[S.length()][T.length()];
    }
}

Approach II: DP with O(n)

Time: O(mn), Space: O(n)

public class Solution {
    public int numDistinct(String S, String T) {
        if(S.length() < T.length()) return 0;
        int[] f = new int[T.length()+1];
        f[0] = 1;
        for(int i = 1; i <= S.length(); i++){
            for(int j = T.length(); j >= 1; j--){
                if(S.charAt(i-1) == T.charAt(j-1)){
                    f[j] += f[j-1];
                }
            }
        }
        return f[T.length()];
    }
}

Question: I don't know why we need to loop j decreasingly?

// j应该从尾到头,因为每次要使用上一次loop的值。如果从头往尾扫的话,重复计算了。

Reference: http://fisherlei.blogspot.com/2012/12/leetcode-distinct-subsequences_19.html

But why don't Minimum Path Sum loop j increasingly? 

### 回答1: EDSDK 13.11是佳能公司最新的软件开发工具包。它提供了丰富的API,使得开发者可以方便地进行佳能数码相机的应用开发。EDSDK 13.11支持全系列佳能数码相机,并且兼容Windows和MacOS操作系统。开发者可以使用EDSDK 13.11创建各种类型的应用程序,例如拍摄控制应用程序、图像处理应用程序以及远程控制应用程序等等。 EDSDK 13.11包含了众多方便的功能模块,例如从相机获取实时图像、设置相机参数、拍摄图像、存储图像等等。此外,它还支持对拍摄图像进行各种处理,例如调整亮度、对比度、色彩等等。EDSDK 13.11甚至还支持在应用程序中对相机进行远程控制,从而实现更加灵活的应用。 EDSDK 13.11同时也提供了丰富的开发文档和示例代码,方便开发者快速了解使用EDSDK 13.11进行开发的方法和技巧。EDSDK 13.11的使用简单、功能强大、支持全系列佳能数码相机,是目前最好的佳能相机开发工具之一。 ### 回答2: Edsdk 13.11是指Canon的EOS Digital Software Development Kit (Edsdk)软件开发工具包的版本号。该工具包是为Canon相机的开发者和软件工程师提供的一套API(应用程序编程接口),允许他们开发基于Canon相机的软件,包括控制相机、传输图片、图像处理等。 Edsdk 13.11版本更新了一些功能和bug修复,为开发者提供了更广泛的应用场景。例如,它支持编写应用程序的过程中控制手机的LIVE VIEW画面,可以获取多个录像文件的基本信息,也可以通过PtpObjectInfo API获取CDL(color decision list)信息。 对于Canon相机的爱好者和专业人士来说,Edsdk 13.11是一个必不可少的工具,使他们能够更好地利用相机提供的高质量的素材。同时,这个软件工具包也为Canon公司保持了他们相机技术的领先地位提供了支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值