算法 | 判定字符串的子序列

审题

这是力扣上的一道算法题(392. 判断子序列[1])。判断给定的字符串 s(较短)是否是字符串 t(较长)的子序列。

“子序列”和“子串”是 2 个概念,要注意区分。

举个例子。

如果说 s 是 t 的 “子串”,就表示 t.includes(s) 返回 true

而 “子序列” 只是表示 s 中每个字符的出现顺序跟 t 中是一样的。比如,虽然 "abcde".includes("ace") 返回 false,但 “ace” 就是 “abcde” 的一个子序列

也就是说,如果 s 是 t 的 “子串”,那么 s 必然也是 t 的 “子序列”,反之就不行。

理解了“子序列”的概念,就可以做题了。

函数定义如下。

/**
 * @param {string} s
 * @param {string} t
 * @return {boolean}
 */

var isSubsequence = function(s, t{
  // ...
}

分析

我的思路是,在遍历 t 中每个字符时,我们就能判定 s 是否使它的子序列了。

假设,要判定的 s 是 “ace”,t 是 “abcde”。

首先,声明 2 个索引 i 和 j,初始值都为 0。

 ↓i
"ace"
"abcde"
 ↑j

i 表示当前 “ace” 中要匹配的字符索引,j 则表示当前 “abcde” 正在遍历的字符索引。

此时,i 和 j 所处索引位置都为 “a”,匹配!i 和 j 同时进 1。

  ↓i
"ace"
"abcde"
  ↑j

“c” 和 “b” 不等。i 不变,j 进 1。

  ↓i
"ace"
"abcde"
   ↑j

“c” 和 “c” 相等,匹配!i 和 j 同时进 1。

   ↓i
"ace"
"abcde"
    ↑j

“e” 和 “d” 不等。i 不变,j 进 1。

   ↓i
"ace"
"abcde"
     ↑j

“e” 和 “e” 相等,匹配!i 和 j 同时进 1。

     ↓i
"ace"
"abcde"
       ↑j

遍历结束。

此时,i 的值等于 3,表示 “ace” 中的字符都匹配完成,说明 “ace” 是 “abcde” 的子序列。

实现

按照这个思路,我们来写代码。

var isSubsequence = function(s, t{
  let i = j = 0
  
  for (; j < t.length; j++) {
    if (t[j] === s[i]) {
      i++
    }
  }
  
  if (i === s.length) {
    return true
  } else {
    return false
  }
}

甚至都不需要索引 j

var isSubsequence = function (s, t{
    let i = 0

    for (let char of t) {
        if (char === s[i]) {
            i++
        }
    }

    if (i === s.length) {
        return true
    } else {
        return false
    }
};

总结

本文我们完成了子序列的判定。在此之前,要先了解“子序列”和“子串”的区别。

实现思路如下。

  1. 在遍历长串 t 的过程中,借助一个索引 i(初始值 0)指向当前短串 s 中要匹配的字符
  2. 一旦字符匹配,i 值进 1——指向 s 中新的要匹配的字符
  3. 待 t 完成遍历后,如果 i 的值恰好等于 s.length,就表明 s 中的所有字符都完成了匹配,s 是 t 的子序列,反之就不是

希望本文的讲解对你有所帮助。感谢阅读,再见。

参考资料
[1]

392. 判断子序列: https://leetcode.cn/problems/is-subsequence


原文始发于微信公众号(写代码的宝哥):算法 | 判定字符串的子序列

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/245865.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!