LeetCode_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.

  

class Solution {
public:
        
    
    void DFS(string S, string T,int si,int num, vector<char> &tp)
    {
       
      if(num == sizeB){
             answer ++;
             return ;
      }
      
      if(si >= sizeA || num > sizeB)
         return ;
    
      for(int i = si; i<sizeA ; i++)
      {
          if(S[i] == T[num])
            {
         tp.push_back(S[i]) ;
         DFS(S,T,i+1, num+1, tp);
         tp.pop_back() ;
         
         }
      }
    }
    int numDistinct(string S, string T) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        sizeA = S.size();
        sizeB = T.size();
        
        if(sizeA < sizeB) return 0;
        
         answer = 0;
         int i;
         for( i=0 ; i< sizeA  ; i++)
               if(S[i] == T[0])
                  break ;
         
         if(i < sizeA)
         {
         
           vector<char> tp;
           DFS(S,T,i,0,tp) ;
          
          }
          
          return answer;
    }
private :
  int answer ;
  int sizeA;
  int sizeB;
 
};

上述代码使用DFS来做,大数据还过不了

DP:

将“S串中前m个字母的子串中包含多少个T串中前n个字母的子串”这样的问题记为A[m][n]。 可以得到递推式 :
if(S[m-1] == T[n-1]) A[m][n] = A[m-1][n-1] + A[m-1][n];
else A[m][n] = A[m-1][n-1];
再处理边界情况即可。简单起见,用类似打表记录式的递归实现。

class Solution {
public:
        
    int Dp(int m, int n, int *tp, const string &S,const string & T )
    {
      
       if(n == -1) return 1;
        else if(m == -1) return 0;
        
        if(m < n) return 0;
       if( tp[m*sizeB+n] != -1 )
         return tp[m*sizeB+n];
         
        tp[m*sizeB+n] =  S[m] == T[n] ? Dp(m-1, n-1,tp, S, T) + Dp(m-1, n,tp,S,T) :
                            Dp(m-1, n,tp,S,T) ;
    
        return tp[m*sizeB+n];
    }
  
    int numDistinct(string S, string T) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        sizeA = S.size();
        sizeB = T.size();
       int *tp = new int[sizeA * sizeB] ;
       for(int i = 0; i< sizeA * sizeB ;i++)
           tp[i] = -1;
       
       return Dp(sizeA-1, sizeB-1,tp,S, T) ;
      
    }

 private :
    
    int sizeA;
    int sizeB;
};

上面必须先判断n == -1,在判断m == -1. 很重要。 

 

一种写法:

class Solution {
public:
    int numDistinct(string S, string T) {
        // Note: The Solution object is instantiated only once and is reused by each test case.
     //if(S == null || T == null) return -1;
     int lens = S.size();
     int lent = T.size();
     
     if(lens == 0 || lent == 0) return 0;
     vector<vector<int>> m(lent+1,vector<int>(lens+1,0));
     for(int j = 0; j <= S.length(); j++) m[0][j] = 1;
    
     for(int i = 1; i <= lent; i++)
        for(int j = i; j <= lens; j++)
            m[i][j] = T[i-1] != S[j-1] ? m[i][j-1] : m[i-1][j-1] + m[i][j-1];
     
     return m[lent][lens]; 
    }
};

节省空间的写法:

class Solution {
public:
    int numDistinct(string S, string T) {
        // Note: The Solution object is instantiated only once and is reused by each test case.
    int M = T.length(); //subsequence length
    int N = S.length(); 
    if (M > N || M ==0 || N==0) {
        return 0;
    }
    vector<int> m(M, 0);    
    m[0] = (T[0] == S[0]?1:0);
    for (int i=1; i<N; ++i) {         
        for(int j=min(i,M); j>=1;--j) {
            m[j] = m[j] + ((S[i]==T[j])?m[j-1]:0);
        }
        m[0] = m[0] + (S[i]==T[0]?1:0);
    }        
    return m[M-1];
    }
};

 

posted @ 2013-07-16 19:44  冰点猎手  阅读(218)  评论(0编辑  收藏  举报