栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java描述 LeetCode,115. Distinct Subsequences

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java描述 LeetCode,115. Distinct Subsequences

大家好,我是河海哥,专注于后端,如果可以的话,想做一名code designer而不是普通的coder,一起见证河海哥的成长,您的评论与赞是我的最大动力。

1-1:题目:

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

A string’s subsequence is a new string formed from the original string by deleting some (can be none) of the characters without disturbing the remaining characters’ relative positions. (i.e., “ACE” is a subsequence of “ABCDE” while “AEC” is not).

It is guaranteed 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.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/distinct-subsequences

1-2:idea

这道题,如果你和我一样有392的思路:https://blog.csdn.net/qq_41376740/article/details/121294391,这道题基本上列个表就可以写下去了。只不过这边的s是长字符串,t是短字符串。同样,按照之前的思路,我们dp几步先走下来:

  • dp状态:dp[i][j]:以t[i]结尾的t[0:i]的序列 在以s[j]结尾的s[0:j]的序列中可以找到dp[i][j]个
  • 状态转移方程:
    • t[i] == s[j] 的时候,就有点问题了,我一开始直接写的dp[i][j] = dp[i - 1][j - 1];后来看了答案,发现还有一种情况,比如s = rabb,t = rabbb,如果只考虑dp[i][j] = dp[i - 1][j - 1] 那么只有s=rabb,t=rab_b,t=ra_bb,也就是最后一个b是必选的,但是事实上还有t=rabb_这种情况,所以dp方程应该是dp[i][j] = dp[i - 1][j - 1] + dp[i][j - 1];
    • t[i] != s[j] 的时候,很好处理,dp[i][j] = dp[i][j - 1];
  • 初始化:空字符串肯定是其他字符串的子串,所以dp[0][j] = 1;,非空字符串不是空字符串的子序列,所以第一列其他位置都是0;
  • 确定遍历顺序:很好理解
1-3:代码
public static int numDistinct(String s, String t) {
    int n = t.length();
    int m = s.length();

    int[][] dp = new int[n + 1][m + 1];
    for (int i = 0; i <= m; i++) {
        dp[0][i] = 1;
    }

    for (int i = 1; i < n + 1; i++) {
        for (int j = i; j < m + 1; j++) {
            if (t.charAt(i - 1) == s.charAt(j - 1)) {
                if (i == j) {
                    dp[i][j] = dp[i - 1][j - 1];
                }else {
                    dp[i][j] = dp[i - 1][j - 1] + dp[i][j - 1];
                }
            } else {
                dp[i][j] = dp[i][j - 1];
            }
        }
    }

    System.out.println(Arrays.deepToString(dp));
    return dp[n][m];
}
打表:
     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]

代码可以用滚动数组优化,但是吧,我感觉除非做过,能上来就用滚动数组写吗?现在的我还做不到QAQ。

1-4:总结

这道题其实不难,如果有之前的基础,做起来还是不那么难的,只是要考虑全面,我这里是有一个情况没有考虑到导致AC失败了。总的看来还行,至少比前面要好一些了。继续加油啊!河海哥,冲!如有错误还请指正,不胜感激,你的赞和评论是我最大的动力。一起加油!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/489275.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号