持续创作,加速成长!这是我参与「掘金日新计划 · 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 <= 100a和b由小写英文字母组成
题解:思维
- 如果两个字符串相同,则无论如何都找不到特殊序列,于是返回-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 <= 501 <= strs[i].length <= 10strs[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;
}
};