「LeetCode」522-最长特殊序列 II

102 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情

一.题目:

522. 最长特殊序列 II 给定字符串列表 strs ,返回其中 最长的特殊序列 。如果最长特殊序列不存在,返回 -1 。

特殊序列 定义如下:该序列为某字符串 独有的子序列(即不能是其他字符串的子序列)

s 的 子序列可以通过删去字符串 s 中的某些字符实现。

  • "aebdc"的子序列还包括"aebdc"、 "aeb" 和 "" (空字符串)。例如,"abc" 是 "aebdc" 的子序列,因为您可以删除"aebdc"中的下划线字符来得到 "abc" 。

示例 1:

输入: strs = ["aba","cdc","eae"]
输出: 3

示例 2:

输入: strs = ["aaa","aaa","aa"]
输出: -1

提示:

  • 2 <= strs.length <= 50
  • 1 <= strs[i].length <= 10
  • strs[i] 只包含小写英文字母

二、思路分析:

这道题目需要仔细地审题,不然盲目地做就是在浪费时间。读懂题目我们才知道我们要找到的那个最长的特殊序列是除了它自身不能够是其他字符串的子序列,即我们应该找到最大的不被其他字符串包含的目标字符串。所以基本步骤如下:

  • 既然是寻找最大的不被其他字符串包含的目标字符串,那么我们第一件要做的事就是排序,将长度长的排在前面,这样我们找到了一个符合要求的字符串就可以直接返回而不需要继续循环。
  • 我们利用一个check来标记是否符合,如果不符合要求则需要继续遍历,如果符合直接跳出循环返回结果即可。
  • 至于寻找子序列的算法就是采用双指针的做法,如果两个字符串的字符相同则同时向前移动,如果不符合则单个指针移动,结果返回是或不是。

三、代码:

function findLUSlength(strs: string[]): number {
    const n = strs.length;
    let res = -1;
    const isSub = (s1:string, s2:string) => {
        if(s1.length === s2.length){
            return s1 === s2;
        }
        let p1 = 0, p2 = 0;
        while(p1 < s1.length && p2 < s2.length){
            if(s1[p1] === s2[p2]){
                p1++;
            }
            p2++
        }
        return p1 === s1.length;
    }
    strs.sort((a,b) => b.length - a.length);
    for(let i=0 ; i<n ; i++){
        let check = true;
        for(let j=0 ; j<n ; j++){
            if(isSub(strs[i],strs[j]) && i !== j){
                check = false;
                break;
            }
        }
        if(check){
           res = strs[i].length;
           break;
        }
    }
    return res
};

四、总结:

这道题目需要我们仔细地审题发现题目的隐含信息,基本上这道题就是基本的循环+排序+双指针的思路,比较不容易想到排序,如果不利用排序的话也是可以做出来的只不过时间复杂度稍微高了些。