双指针 - 最长子序列

Posted GoldenaArcher

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双指针 - 最长子序列相关的知识,希望对你有一定的参考价值。

双指针 - 最长子序列

题目:524. Longest Word in Dictionary through Deleting

题目如下:

Given a string s and a string array dictionary, return the longest string in the dictionary that can be formed by deleting some of the given string characters. If there is more than one possible result, return the longest word with the smallest lexicographical order. If there is no possible result, return the empty string.

解题思路:

这道题不长,但是有几个要点需要注意

  1. 什么是子序列

    原文这里是这样描述定义的:

    longest string in the dictionary that can be formed by deleting some of the given string characters

    也就是说,提供的字符串,为了方便称呼这里称其 a,删除掉一些字符能够组成字典中的字符串时,该字符串就是 a 的子序列

    举例说明:

    如提供的字符串 a 是 apple,需要比对的字符串是 ape,通过删除 pl,apple 可以转化为 ape,所以 ape 是 apple 的子序列

    注意,题目中只标注了删除 deleting,没有标注重新排序,所以乱序的事情不用考虑,这也是为什么这道题能够用双指针的关系

  2. 什么是 字典排序(lexicographical order)

    就是按照 26 个字母排序的顺序,也就是在 a-z 中,a < < < b,b < < < c 这种逻辑。

    所以说当字符串长度相同是,如 app 与 ale 的对比,因为 l 在 26 个字母中排序小于 p 所以 ale < < < ap:

    console.log('ale' < 'ape'); // true
    
  3. 依旧是用双指针来解题

根据解题思路解题:

/**
 * @param {string} s
 * @param {string[]} dictionary
 * @return {string}
 */
var findLongestWord = function (s, dictionary) {
  let longestWord = '';
  for (const substr of dictionary) {
    if (isSubSqeuence(s, substr)) {
      // find longest
      if (substr.length > longestWord.length) {
        longestWord = substr;
      } // find smallest lexicographical order
      else if (substr.length === longestWord.length) {
        longestWord = substr < longestWord ? substr : longestWord;
      }
    }
  }
  return longestWord;
};

const isSubSqeuence = (s, substr) => {
  let strIndex = 0,
    substrIndex = 0;
  // during each iteration, match the current str index with substr index
  while (strIndex < s.length && substrIndex < substr.length) {
    // if both chars match, then increment substr index
    if (s[strIndex] === substr[substrIndex]) {
      substrIndex++;
    }
    strIndex++;
  }
  // once iteration is done, valid substr index must match the lenth of substr
  return substrIndex === substr.length;
};

console.log(findLongestWord((s = 'abpcplea'), (dictionary = ['a', 'b', 'c'])));
console.log(
  findLongestWord(
    (s = 'abpcplea'),
    (dictionary = ['ale', 'apple', 'monkey', 'plea'])
  )
);

javascript 的大小写原生就可以比对字典排序,这部分 MDN 也有说明:

In C, the strcmp() function is used for comparing strings. In JavaScript, you just use the less-than and greater-than operators:

let a = 'a';
let b = 'b';
if (a < b) {
  // true
  console.log(a + ' is less than ' + b);
} else if (a > b) {
  console.log(a + ' is greater than ' + b);
} else {
  console.log(a + ' and ' + b + ' are equal.');
}

如果想要看起来更“正式”的用法,也可以考虑使用 str.localeCompare(str2)localeCompare() 是字符串实例继承了操作符的函数,所以会有相似的结果。

不管怎么样,直接用 < < < 搭配三元表达式就可以进行计算这点也是挺方便的,而且从效率上来说,看起来还不错:

以上是关于双指针 - 最长子序列的主要内容,如果未能解决你的问题,请参考以下文章

ACWing 最长连续不重复子序列(双指针)

算法学习——双指针算法(最长连续不重复子序列)

双指针—最长连续不重复子序列

最长连续不重复子序列(双指针算法)

15.最长连续不重复子序列

[leetcode] 522. 最长特殊序列 II 暴力 + 双指针