算法:还有比二分查找更快的算法,判断是否是子字符串Is Subsequence

题目

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

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

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?

Credits:

Special thanks to @pbrother for adding this problem and creating all test cases.

Example 1:

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

Example 2:

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

Constraints:

  1. 0 <= s.length <= 100
  2. 0 <= t.length <= 10^4
  3. Both strings consists only of lowercase characters.

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/is-subsequence

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法一

解决思路:笔者看这道题是二分查找的类型题,很自然就从二分查找,用左右两个坐标同时来匹配。短字符串s的左坐标为sleft, 右坐标为sright; 长字符串t的左坐标为tleft, 右坐标为tright.

检查边界问题,比如短字符为空s == null || s.length() == 0, 则直接返回true;如果长字符为空t == null || t.length() == 0,则直接返回false;

循环遍历条件为长字符串tleft <= tright , 在循环结束前tleft++; tright–;。

如果短字符串的左边字符等于长字符串的左边字符串,则sleft++;;如果短字符串的右边字符等于长字符串的右边字符串,则sright–;。

在结束前判断短字符串的sleft > sright,则返回true。 注意:笔者这里踩过坑,如果放到最前面判断,有可能,长字符串也结束了,导致结果还是false。

public boolean isSubsequence(String s, String t) {
    // check edge for s
    if (s == null || s.length() == 0) {
      return true;
    }
    // check edge for t
    if (t == null || t.length() == 0) {
      return false;
    }
    boolean result = false;
    int sleft = 0;
    int sright = s.length() - 1;
    int tleft = 0;
    int tright = t.length() - 1;
    while (tleft <= tright) {
      if (s.charAt(sleft) == t.charAt(tleft)) {
        sleft++;
      }
      if (s.charAt(sright) == t.charAt(tright)) {
        sright--;
      }
      
      if (sleft > sright) {
        return  true;
      }
      tleft++;
      tright--;
    }
    return result;
  }

解法二

笔者跑完以后,以为速度会是最快了,看了以后只能超过87%的提交。看了一下评论,发现还有更优解。

解题思路如下:

遍历短字符串的所有字符,比如遍历到短字符的c,如果长字符集能从前一个找到的字符的位置加一(第一个字符的初始值为-1),能找到当前字符c,则返回第一次找到该字符的位置,则替换index为上一个找到的字符集;如果没有找到当前字符c,则结果是-1,如果是-1,则直接返回false。时间复杂度只有最短字符的长度,最快的情况下,如果第一个字符都没找到就直接退出。神来之笔。

public boolean isSubsequenceByIndexOfChar(String s, String t) {
    int index = -1;
    for (char c: s.toCharArray()) {
      index = t.indexOf(c, index + 1);
      if (index == -1) {
        return false;
      }
    }
    return true;
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值