522. 最长特殊序列 II

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

特殊序列 定义如下：该序列为某字符串 独有的子序列（即不能是其他字符串的子序列）。

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

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

示例 1：

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

示例 2:

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

提示:

2 <= strs.length <= 50

1 <= strs[i].length <= 10

strs[i] 只包含小写英文字母

枚举

假如 strs = [ "abc", "abcd", "abcde" ]，"abcd" 不是 "abc" 的子序列，但 "abcd" 是 abcde 的子序列，"abcde" 不是 "abcd"的子序列，也不是 abc 的子序列，所以我们要找的最长特殊序列即为 "abcde"。

代码实现：

Copy
class Solution {
public:
int findLUSlength(vector<string>& strs) {
// str1 是否为 str2 的子序列
auto isSub = [&](const string &str1, const string &str2) -> bool {
int j = 0;
for (int i = 0; i < str2.size(); ++i) {
if (str1[j] == str2[i]) {
++j;
}
}
return j == str1.size();
};

int res = -1;
for (int i = 0; i < strs.size(); ++i) {
bool flag = true;
// 当遍历的字符串的长度大于最长特殊序列长度时最长特殊序列长度才有增加的可能
if (strs[i].size() > res) {
for (int j = 0; j < strs.size(); ++j) {
if (j != i && isSub(strs[i], strs[j])) {
flag = false;
break;
}
}
if (flag) {
res = strs[i].size();
}
}
}

return res;
}
};

这道题其实不难，但是很容易错，上面的代码其实是存在 bug。

bug 就在判断对当前遍历的长度的判断是否大于最长特殊序列的长度上 if (strs[i].size() > res)，size() 返回类型为 size_t，是一个无符号类型，而 res 是一个有符号类型，在比较时 res 进行了整形提升，res 从有符号类型隐式转换为无符号类型，res 在 64 位操作系统上 res 的值变为 264+1 2^{64}+1264+1。除了该位置的隐式转换，还有多处隐式转换问题。