(Java) LeetCode 392. Is Subsequence —— 判断子序列

Given a string s and a string t, check if s is subsequence of t.

You may assume that there is only lower case English letters in both s and t. t is potentially a very long (length ~= 500,000) string, and sis a short string (<=100).

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

Example 1:
s = "abc", t = "ahbgdc"

Return true.

Example 2:
s = "axc", t = "ahbgdc"

Return false.

Follow up:
If there are lots of incoming S, say S1, S2, ... , Sk where k >= 1B, and you want to check one by one to see if T has its subsequence. In this scenario, how would you change your code?



解法一(贪心算法):其实有点像字符串匹配的问题。如果维持两个指针分别指向两个字符串起点并开始遍历,找到匹配就移动两个指针向后,找到不匹配只移动待搜索的字符串的指针以寻找下一个匹配点。最后判断时候目标字符串已被遍历完成即可。思路很简单,而且是有一种“贪心”的想法在里面,即遇到匹配的就加入。

解法二(动态规划):看到follow up和标签,想想其他的办法。首先动态规划是一定可以做的。假设boolean dp[i][j]表示s从0到i位置的字符串是否是t从0到j位置字符串的子串。那么当s[i]和t[j]相等的时候,只需要判断s(0, i-1)是不是t(0, j-1)的子串;如果s[i]和t[j]不相等,那么要一直往前看s(0, i)是不是t(0, j-1)的子串。只要注意边界情况就好。如果j是0,即t只有一个字符的时候都还没有能和s匹配,那么一定是不匹配。而且如果i>j,那么dp[i][j]一定是false,因为短字符串没法匹配长字符串。把递推公式实现,就是动态规划的解法。虽然运行速度很慢,但还是能过,显然这个方法是被允许的。

解法三(二分查找):最后想一下,如果输入是大量的s需要进匹配那要怎么做。s可以有很多,但t只有一个。如果把t里面每个字符出现时的索引存起来,这样遇到一个s,那就看首先s中的字符在t中有没有出现(即存储那个索引的结构是不是空),没有出现直接返回false。如果出现了,那么记下它在t中出现的位置,比如设为preIndex,之后搜索s中下一个字符。这时候如果字符仍然在t中存在,那其实应该寻找第一个大于preIndex的位置(即寻找第一个大于等于preIndex+1的索引)才可以实现匹配。在有序结构里寻找特定数,就是标签中有二分查找的由来。



解法一(Java)

public class Solution {
    public boolean isSubsequence(String s, String t) {
        int i = 0, j = 0;
        while(i < s.length() && j < t.length()) {
            if(s.charAt(i) == t.charAt(j)) i++;
            j++;
        }
        if(i == s.length()) return true;
        return false;
    }
}

解法二(Java)

public class Solution {
    public boolean isSubsequence(String s, String t) {
        int m = s.length(), n = t.length();
        if (m == 0) return true;
        if (n == 0) return false;
        boolean[][] dp = new boolean[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (i > j) dp[i][j] = false;
                else if (s.charAt(i) == t.charAt(j)) {
                    if (i == 0 || j == 0) dp[i][j] = i <= j ? true : false;
                    else           dp[i][j] = dp[i-1][j-1];
                }
                else dp[i][j] = j == 0 ? false : dp[i][j-1];
            }
        }
        return dp[m-1][n-1];
    }
}

解法三(Java)

public class solution {
    public boolean isSubsequence(String s, String t) {
        int m = s.length(), n = t.length();
        if (m == 0) return true;
        if (n == 0) return false;
        List<Integer>[] list = new List[256];
        for (int i = 0; i < n; i++) {
            char c = t.charAt(i);
            if (list[c] == null) list[c] = new ArrayList<Integer>();
            list[c].add(i);
        }
        int preIndex = -1;
        for (int i = 0; i < m; i++) {
            char c = s.charAt(i);
            if (list[c] == null) return false;
            int index = binarySearch(list[c], preIndex + 1);
            if (index == -1) return false;
            else preIndex = index;
        }
        return true;    }

    public int binarySearch(List<Integer> list, int key) {
        int lo = 0, hi = list.size() - 1;
        while (lo < hi) {
            int mid = lo + (hi - lo) / 2;
            if (key > list.get(mid)) lo = mid + 1;
            else hi = mid;
        }
        if (list.get(hi) < key) return -1;
        return list.get(hi);    }
}

原文地址:https://www.cnblogs.com/tengdai/p/9243326.html

时间: 2024-10-07 22:20:13

(Java) LeetCode 392. Is Subsequence —— 判断子序列的相关文章

LeetCode | 0392. Is Subsequence判断子序列【Python】

LeetCode 0392. Is Subsequence判断子序列[Easy][Python][双指针] Problem LeetCode Given a string s and a string t, check if s is subsequence of t. You may assume that there is only lower case English letters in both s and t. t is potentially a very long (length

[LeetCode] 392. Is Subsequence Java

题目: Given a string s and a string t, check if s is subsequence of t. You may assume that there is only lower case English letters in both s and t. t is potentially a very long (length ~= 500,000) string, and sis a short string (<=100). A subsequence

LeetCode 376. Wiggle Subsequence 摆动子序列

原题 A sequence of numbers is called a wiggle sequence if the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than t

LeetCode:递增的三元子序列【334】

LeetCode:递增的三元子序列[334] 题目描述 给定一个未排序的数组,判断这个数组中是否存在长度为 3 的递增子序列. 数学表达式如下: 如果存在这样的 i, j, k,  且满足 0 ≤ i < j < k ≤ n-1,使得 arr[i] < arr[j] < arr[k] ,返回 true ; 否则返回 false . 说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1) . 示例 1: 输入: [1,2,3,4,5] 输出: true 示例 2: 输入:

Java [Leetcode 119]Pascal&#39;s Triangle II

题目描述: Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3,Return [1,3,3,1]. 解题思路: 每次在上一个list前面插入1,然后后面的每两个间相加赋值给前一个数. 代码描述: public class Solution { public List<Integer> getRow(int rowIndex) { List<Integer> r

LeetCode OJ - Distinct Subsequence

这道题采用动态规划,可是我一开始没有想到.后来参考了discuss中前辈的代码和思路,才想通的. 方法二是因为每一步只和上一步的内容相关,所以可以只用O(n)的空间复杂度. 下面是AC代码: 1 /** 2 * Solution DP 3 * we keep a m*n matrix and scanning through string T, 4 * p[i][j] means the number of distinct subsequence of S(0...j) equal to T(

C#与Java对比学习:类型判断、类与接口继承、代码规范与编码习惯、常量定义(转载)

C#与Java对比学习:类型判断.类与接口继承.代码规范与编码习惯.常量定义 类型判断符号: C#:object a;  if(a is int) { }  用 is 符号判断 Java:object a; if(a instanceof Integer) { } 用 instanceof 符号判断 类与接口的继承: C#:public class MDataRow : List<MDataCell>, IDataRecord, ICustomTypeDescriptor Java:publi

Java杂谈之二----怎样判断一个数是水仙花数以及穷举水仙花数

首先明确一下什么是水仙花数 百度说,水仙花数指一个n位数(n>=3),它的每个位上的数字的n次幂之和等于它本身 例如:1^3+5^3+3^3=153 水仙花数只是自幂数的一种,严格来说三位数的3次幂数才能成为水仙花数. 但其实也分一位自幂数,两位自幂数,三位自幂数,四位自幂数等等. 所以鉴于水仙花数的定义的不确定和模糊性 以下代码示例不仅限于三位数的水仙花数,主要涉及的是思想问题. 类名:JavaNarcissus 构造函数:JavaNarcissus() 判断一个数是否为水仙花数:IsNarc

java编写输入一个数判断是否是回文数,所谓回文数比如121,1221,6778776

package com.hao947; import java.util.Scanner; public class demo5 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int x = 0; x = scanner.nextInt(); System.out.println("请输入一个4-8位的数"); int dig[] = new int[10]; i