LeetCode: 392. 判断子序列

题目:
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。

你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。

字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。

解析

我看到这题,就知道肯定是要遍历一遍t的。而且s在t中的相对位置不变,所以:

  • 当s的字符在t中出现了,那就只用考虑在此之后的序列了。因为相对位置不变。
class Solution:
    def isSubsequence(self, s: str, t: str) -> bool:
        length = len(s)
        j = 0
        if len(s) == 0:
            return True
        if len(s) !=0 and len(t) == 0:
            return False
        for i in t:
            if i == s[j]:
                j += 1
            if j == length:  
            # 当j等于length,
            # 说明s的字符按照相对顺序,都出现在s中,,提前return
                return True
        return False
            

另外写了一种用map的方法。适合要判断多个子序列问题。

  • 先遍历一次t,用哈希表记录每个字符出现的位置。
  • 遍历一次s。用tag记录s中字符在前一个字符对应的t中的位置之后最近的位置。比如前一个s中的字符在t中第i个位置出现了。那么tag为i。寻找s中后一个字符在t的第i+1之后,最先出现当前遍历s得到的字符的在t中的位置。把这个位置再次赋值给tag。还是能按顺序比较。
  • 其中二分查找是为了寻找第一个符合要求的字符。
class Solution:
    def isSubsequence(self, s: str, t: str) -> bool:
        dic = {}
        for i, a in enumerate(t):
            if not dic.get(a, None):
                dic[a] = []
            dic[a].append(i)
        tag = -1
        for i in range(len(s)):
            pos = dic.get(s[i], None)
            if pos is None:
                return False
            head, tail =0, len(pos)-1
            while head < tail:
                mid = (head + tail) >> 2
                if pos[mid] > tag:
                    tail = mid
                else:
                    head = mid + 1
            if tail < head or pos[head] < tag:
                return False
            tag = pos[head]    
        return True   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值