【LeetCode每日一题】521:最长特殊序列 Ⅰ

116 阅读2分钟

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

LeetCode每日一题打卡专栏正式启动!不出意外将日更LeetCode的每日一题,敬请期待。

521:最长特殊序列 Ⅰ

题意

给你两个字符串 a 和 b,请返回 这两个字符串中 最长的特殊序列 。如果不存在,则返回 -1 。

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

字符串 s 的子序列是在从 s 中删除任意数量的字符后可以获得的字符串。

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

示例1:

输入: a = "aba", b = "cdc"
输出: 3
解释: 最长特殊序列可为 "aba" (或 "cdc"),两者均为自身的子序列且不是对方的子序列。

示例2:

输入:a = "aaa", b = "bbb"
输出:3
解释: 最长特殊序列是“aaa”和“bbb”。

示例3:

输入:a = "aaa", b = "aaa"
输出:-1
解释: 字符串a的每个子序列也是字符串b的每个子序列。同样,字符串b的每个子序列也是字符串a的子序列。

提示:

  • 1 <= a.length, b.length <= 100
  • ab 由小写英文字母组成

题解:思维

  • 如果两个字符串相同,则无论如何都找不到特殊序列,于是返回-1
  • 如果两个字符串不同,则长度长的字符串肯定是最长特殊序列。(当然如果长度相同,则两个任选一个都是)

C++代码:

class Solution {
public:
    int findLUSlength(string a, string b) {
        int len1=a.length();
        int len2=b.length();
        if(a==b&&len1==len2){
            return -1;
        }
        return max(len1,len2);
    }
};

Java代码:

class Solution {
    public int findLUSlength(String a, String b) {
        int len1=a.length();
        int len2=b.length();
        if(len1==len2&&a.equals(b)) return -1;
        return Math.max(len1,len2);
    }
}

扩展:最长特殊序列 II

题意

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

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

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

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

示例1:

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

示例2:

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

提示:

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

题解

首先需要知道这样一个性质:最长的符合“该字符串不是数组中其他字符串的子序列”的子串一定是原字符串。

证明:只要某个子串s不是其他字符串的子串,那么这个这个子串在任意位置添加N个字符得到的结果ss肯定也不是其他字符串的子串。 所以对这个子串s而言,子串s进行添加字母的操作后最长的串就是原字符串。

于是通过二重循环,判断所有字符串是否是其他字符串的子序列,例如:strs[i]不是其他所有字符串的子序列,则strs[i]可能是题目所求的最长特殊序列(因为可能还需要判断长度)

例如:s1,s2,s3都满足自身都不是其他字符串的子序列,则需要判断其中谁的长度最长,假设s3长度最长,则s3为题目所求的最长特殊序列

C++代码:

class Solution {
public:
    bool check(string s1,string s2){
        int i,j;
        for(i=0,j=0;i<s1.length()&&j<s2.length();j++){
            if(s1[i]==s2[j]) i++;
        }
        return i==s1.length()?true:false;
    }
    int findLUSlength(vector<string>& strs) {
        int n=strs.size();
        int ans=-1;
        for(int i=0;i<n;i++){
            int flag=0;
            for(int j=0;j<n;j++){
                if(j==i) continue;
                //如果是前面的子序列,则直接结束循环
                if(check(strs[i],strs[j])){
                    flag=1;break;
                }
            }
            if(!flag) ans=max(ans,(int)strs[i].length());
        }
        return ans;
    }
};