LeetCode115 Distinct Subsequences

详细见:leetcode.com/problems/distinct-subsequences


Java Solution: github

package leetcode;


/*
 * 	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.
 */


public class P115_DistinctSubsequences {
	public static void main(String[] args) {
		Solution2 solution = new Solution2();
		String s = null, t = null;
		s = "";	t = "";
		System.out.println(solution.numDistinct(s, t));
		s = "abbc";	t = "ab";
		System.out.println(solution.numDistinct(s, t));
		s = "rabbbit";	t = "rabbit";
		System.out.println(solution.numDistinct(s, t));
		s = "aaaaaaa";	t = "aaa";
		System.out.println(solution.numDistinct(s, t));
		s = "aaaaaaaq";	t = "aaaq";
		System.out.println(solution.numDistinct(s, t));
		s = "aaq";	t = "aaaaaaaaq";
		System.out.println(solution.numDistinct(s, t));
	}
	/*
	 * 	递归是为DP做准备
	 */
	static class Solution1 {
		char[] sc = null, tc = null;
		public int numDistinct(String s, String t) {
			if (s == null || t == null) {
				return t == null ? 1 : 0;
			}
			sc = s.toCharArray();
			tc = t.toCharArray();
			return numDistinct(0,  sc.length - 1, 0, tc.length - 1);
		}
		private int numDistinct(int i, int j, int k, int l) {
			if (j - i < l - k) {
				return 0;
			}
			if (k > l) {
				return 1;
			}
			if (sc[i] != tc[k]) {
				return numDistinct(i + 1, j, k, l);
			} else {
				return numDistinct(i + 1, j, k, l) + numDistinct(i + 1, j, k + 1, l);
			}
		}
	}
	/*
	 * 	这种问题毫无疑问第一方法DP
	 * 	AC
	 * 	15 ms
	 * 	对于这种问题,最好先写出递归版本,对应递归版本,写出dp版本
	 */
	static class Solution2 {
		int[][] dp = null;
		int len1, len2;
	    public int numDistinct(String s, String t) {
	    	if (s == null || t == null) {
				return t == null ? 1 : 0;
			}
	    	len1 = s.length();
	    	len2 = t.length(); 
	    	if (len1 < len2) {
	    		return 0;
	    	}
	    	if (len2 == 0) {
	    		return 1;
	    	}
	    	dp = new int[len1 + 1][len2 + 1];
	    	for (int i = 0; i <= len1; i ++) {
	    		dp[i][len2] = 1;
	    	}
	    	for (int i = len1 - 1; i > -1; i --) {
	    		for (int j = len2 - 1; j > -1; j --) {
	    			dp[i][j] = dp[i + 1][j] +(s.charAt(i) == t.charAt(j) ? dp[i + 1][j + 1] : 0);
	    		}
	    	}
	        return dp[0][0];
	    }
	}
}


C Solution: github

/*
    url: leetcode.com/problems/distinct-subsequences
    unrecur:  AC 6ms 33.33%
    unrecur2: AC 3ms 58.33%
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//TLE
int recur(char* s, char* t) {
    if (*t == '\0') return 1;
    if (*s == '\0') return 0;
    if (*s == *t) return recur(s+1, t) + recur(s+1, t+1);
    else return recur(s+1, t);
}

int unrecur(char* s, char* t) {
    int sn = s == NULL ? 0 : strlen(s);
    int tn = t == NULL ? 0 : strlen(t);
    int i = 0, j = 0, ans = 0;
    int** m = (int**) malloc(sizeof(int*) * (sn+1));
    for (i = 0; i <= sn; i ++) {
        m[i] = (int*) malloc(sizeof(int) * (tn+1));
        for (j = 0; j <= tn; j ++) m[i][j] = 0;
    }
    for (i = 0, j = tn; i <= sn; i ++) m[i][j] = 1;
    for (i = sn-1; i > -1; i --) {
        for (j = tn-1; j > -1; j --) {
            if (s[i] == t[j]) {
                m[i][j] = m[i+1][j] + m[i+1][j+1];
            } else {
                m[i][j] = m[i+1][j];
            }
        }
    }
    ans = m[0][0];
    for (i = 0; i <= sn; i ++) free(m[i]);
    free(m);
    return ans;
}

int unrecur2(char* s, char* t) {
    int sn = s == NULL ? 0 : strlen(s);
    int tn = t == NULL ? 0 : strlen(t);
    int i = 0, j = 0, ans = 0, pre = 0, tmp;
    int* m = (int*) malloc(sizeof(int) * (tn));
    for (j = 0; j < tn; j ++) m[j] = 0;
    for (i = sn-1; i > -1; i --) {
        pre = 1;
        for (j = tn-1; j > -1; j --) {
            tmp = m[j];
            if (s[i] == t[j]) {
                m[j] += pre;
            }
            pre = tmp;
        }
    }
    ans = m[0];
    free(m);
    return ans;
}

int numDistinct(char* s, char* t) {
    return unrecur2(s, t);
}

int main() {
    char* s = "rraaat";
    char* t = "rat";
    printf("%d\r\n", unrecur2(s, t));
    printf("%d\r\n", unrecur(s, t));
}


Python Solution: github

#coding=utf-8

'''
    url: leetcode.com/problems/distinct-subsequences
    @author:     zxwtry
    @email:      zxwtry@qq.com
    @date:       2017年5月1日
    @details:    Solution:  129ms 87.80%
'''

class Solution(object):
    def numDistinct(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: int
        """
        sn = 0 if s == None else len(s)
        tn = 0 if t == None else len(t)
        if (tn == 0): return sn
        if (sn < tn): return 0
        m = [0] * tn
        for i in range(sn-1, -1, -1):
            p = 1
            for j in range(tn-1, -1, -1):
                g = m[j]
                if (s[i] == t[j]):
                    m[j] += p
                p = g
        return m[0]
    
if __name__ == "__main__":
    s = "aaa"
    t = "a"
    print(Solution().numDistinct(s, t))


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值