码迷,mamicode.com
首页 > 其他好文 > 详细

Distinct Subsequences

时间:2015-03-29 17:45:56      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:

https://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.

解题思路:

这再次是一道题意表述不清的题。按照题目的意思,是找出S中所有T的subsequence。这怎么做?其实题目的意思是,S中所有等于T的subsequence。

先想到dfs。搜索S,所有长度等于T的组合里,看有多少和T相等。代码不难,写出来后发现超时了。如下。

public class Solution {
    public int numDistinct(String S, String T) {
        List<String> result = new ArrayList<String>();
        dfs(T, S, new StringBuffer(), result, 0);
        return result.size();
    }
    
    public void dfs(String T, String S, StringBuffer current, List<String> result, int step) {
        if(current.length() > T.length()){
            return;
        }
        if(current.length() == T.length() && T.equals(current.toString())) {
            result.add(current.toString());
            return;
        }
        if(T.indexOf(current.toString()) != 0) {
            return;
        }
        for(int i = step; i < S.length(); i++) {
            current.append(S.charAt(i));
            dfs(T, S, current, result, i + 1);
            current.deleteCharAt(current.length() - 1);
        }
    }
}

于是参考了别人的解法。这是一道动态规划的题目,不过是二维的dp。动态规划的关键在于定义子状态,这里定义dp[i][j]为S[0..i]中的subsequence等于T[0..j]的数量。

如果S[i]!=T[j],S[0...i-1]的subsequence等于T[0..j]的有dp[i-1][j]个,那么在这个基础上加上S[i]也没用,所以dp[i][j]=dp[i-1][j]。

如果S[i]==T[j],那么在上面的基础上加上S[i]就可以了。所以S[0...i-1]的subsequence等于T[0..j-1]的有dp[i-1][j-1]个,因为S[i]==T[j],在这个基础上S加上S[i],T加上T[j],仍然可行,故首先有dp[i-1][j-1]个。还有一种情况,S不加上S[i],仍然拿S[0..i-1]和T[0..j]比,也就是和上面相同,这种情况下还有dp[i-1][j]个。因而,S[i]==T[j]的情况下,dp[i][j]=dp[i-1][j]+dp[i-1][j-1]。

递推方程出来了,动态规划还要解决初始值的问题。对于S=""的情况,也就是i==0,显然所有的dp=0。对于T==""的情况,也就是j==0,dp=1。因为S里的子串等于空的也就一种可能。

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

这还是比较复杂的一道动态规划,因为是二维,状态递推方程也略微复杂,需要细细体会。

Distinct Subsequences

标签:

原文地址:http://www.cnblogs.com/NickyYe/p/4375409.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!