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

Java描述 LeetCode,392. Is Subsequence

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

Java描述 LeetCode,392. Is Subsequence

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

1-1:题目

Given two strings s and t, return true if s is a subsequence of t, or false otherwise.

A subsequence of a string is a new string that is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (i.e., “ace” is a subsequence of “abcde” while “aec” is not).

Example 1:

Input: s = "abc", t = "ahbgdc"
Output: true

Example 2:

Input: s = "axc", t = "ahbgdc"
Output: false

Constraints:

0 <= s.length <= 100
0 <= t.length <= 104
s and t consist only of lowercase English letters.

Follow up: Suppose there are lots of incoming s, say s1, s2, …, sk where k >= 109, and you want to check one by one to see if t has its subsequence. In this scenario, how would you change your code?

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

1-2:自己的idea

这里先写出我自己的思路,我自己的思路和别人都不太一样,最终也AC了(测试用例一共10几个),我也用的dp做。

  1. s是不是t的子序列,这边首先先注意s的长度如果大于t,就不用做啦,肯定就不是的。
  2. dp状态:根据以前题目的经验(比如T1143,T718),我们这边用i作为s的遍历索引,j作为t的遍历索引,并且有如下二维dp状态:dp[i][j]代表以s.charAt(i)结尾的序列s[0:i]是否是以t.charAt(j)的序列s[0:j]的子序列。
  3. 状态转移方程:
    (1)当s.charAt(i) == t.charAt(j),只要子问题s[0:i-1]是t[0:j-1]的子序列,加上s.charAt(i),t.charAt(j),s[0:i] 也是 t[0:j]的子序列。这个很好理解,比如s=ac,t=adc;i=1,j=2,s.charAt(i)=c,t.charAt(j)=c,a是ad的子序列,那么加上c,ac也是adc的子序列。
    (2)当s.charAt(i) != t.charAt(j),比如s=ac,t=ace,i=1,j=2,c不等于e,只要看[0:i]和[0:j-1]的关系,如果是true,那么即使多一个e,ac依旧是ace的子序列。
  4. 初始化,处理边界:由于这边是boolean数组,我们需要对第一行进行初始化。单靠dp状态转移方程是做不到的(或者说,我么做= =,尴尬!我菜啊!)。具体怎么初始化,大概是从相等的开始后面都是true,这边a==a,那么a一定是ab,abc,abcd。。的子序列,没啥问题。蓝色的X代表什么意思呢?这里就是s的子序列比t的子序列长的时候,根本不用考虑,因为s的子序列一定是比t短或者相等的。从红线开始计算即可。
1-3:代码
 public static boolean isSubsequence(String s, String t) {
     int n = s.length();
     int m = t.length();
     if (n == 0) {
         return true;
     }
     if (m == 0 || n > m) {
         return false;
     }
     boolean[][] dp = new boolean[n][m];

     char c = s.charAt(0);
     for (int i = 0; i < m; i++) {
         if (t.charAt(i) == c) {
             for (int j = i; j < m; j++) {
                 dp[0][j] = true;
             }
             break;
         }
     }

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

这边dp数组有效范围是从0开始的,其实从1开始更简单(初始化的时候简单),代码如下,附带列表:

public static boolean isSubsequence3(String s, String t) {
    int n = s.length();
    int m = t.length();
    if (n == 0) {
        return true;
    }
    if (m == 0 || n > m) {
        return false;
    }
    boolean[][] dp = new boolean[n + 1][m + 1];
    for (int i = 0; i <= m; i++) {
        dp[0][i] = true;
    }

    for (int i = 1; i <= n; i++) {
        for (int j = i; j <= m; j++) {
            if (s.charAt(i - 1) == t.charAt(j - 1)) {
                dp[i][j] = dp[i - 1][j - 1];
            } else {
                dp[i][j] = dp[i][j - 1];
            }
        }
    }
    System.out.println(Arrays.deepToString(dp));
    return dp[n][m];
}
         a      b      c      d      e
 [true,  true,  true,  true,  true,  true],
a[false, true,  true,  true,  true,  true], 
c[false, false, false, true,  true,  true], 
e[false, false, false, false, false, true]
1-4:答案的idea

答案的idea 是从之前的一道最长公共子序列 1143题 https://blog.csdn.net/qq_41376740/article/details/121248624,得出的,只要公共最长子序列的长度刚好等于s的长度,也就可以得到s是t的子序列。思路可以看我之前的1143题解

1-5:代码
public static boolean isSubsequence2(String s, String t) {
    int n = s.length();
    int m = t.length();

    int[][] dp = new int[n + 1][m + 1];
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (s.charAt(i - 1) == t.charAt(j - 1)) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
            } else {
                dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
            }
        }
    }
    return dp[n][m] == n;
}
1-6:总结:

这道题也是自己AC出来的,不过我的思路还挺独特的,和别人不一样,也可能测试用例多了就不会通过了,答案的思路还是有点技巧的要想到这么做我觉得不容易,哈哈哈。河海哥的dp越来越有感觉啦!加油吖!如有错误还请纠正,写的还行点个!感谢支持!一起加油!河海哥冲啊!

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

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

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