522. Longest Uncommon Subsequence II
题目:
Given a list of strings, you need to find the longest uncommon subsequence among them. The longest uncommon subsequence is defined as the longest subsequence of one of these strings and this subsequence should not be any subsequence of the other strings.
A subsequence is a sequence that can be derived from one sequence by deleting some characters without changing the order of the remaining elements. Trivially, any string is a subsequence of itself and an empty string is a subsequence of any string.
The input will be a list of strings, and the output needs to be the length of the longest uncommon subsequence. If the longest uncommon subsequence doesn't exist, return -1.
用例:
Input: "aba", "cdc", "eae" Output: 3
题解:
本题目要求的是多个字符串中,最长的不相同子序列长度。理论上来说,将多个字符串进行两两判断,找出在不重复的前提下,最长的字符串,也是一种方法。但显然,长字符为最终成为要求的最长不相同子序列的可能性更大,于是没有必要进行两两比对,只需要将字符串按照长度从长到短进行排序,然后按顺序遍历给出的字符串,然后进行子串的判断,就可以求出答案。具体过程如下:
- 将字符串vector从长到短进行排序,得到strs[0,1,2....n-1]
- 初始化一个集合s作为辅助
- 从0开始遍历strs中的元素strs[i]
- 判断strs[i]与strs[i+1]的长度关系,由于进行过排序操作,strs[i]的长度必然比strs[i+1]大,如果strs[i]==strs[i+1],则无需处理,直接将strs[i]插入到s中(原因:给定["a","a","b","b"],当遍历到第1个"b"时,此时s中只有"a",是没有办法判断"b"是否就是我们最终要求得的最长不同子序列的,于是要将"b"插入到s中待定,在下一个元素中判断)
- 如果strs[i]!=strs[i+1],遍历s中的元素,判断strs[i]是否为任意s中的元素的子串。如果是的话,说明它无法成为最终要求的答案,这时候将str[i]插入到s中;否则,strs[i]就是strs中的最长不相同子串,程序返回strs[i]的长度
举例:
- strs = "aba,abaa,cbc"
- 将字符串进行排序,得到排序后结果:strs = "abaa,aba,cbc"
- 一开始s中没有元素,而abaa比aba要长,意味abaa不是s中任意字符串的子串,得到答案4
- strs = "aba,bac,cab"
- 将字符串进行排序,得到strs = "aba,bac,cab"
- aba与bac的长度相同,意味着aba直接插入到s中
- bac与cab的长度也相同,直接插到到s中
- 将cab与s中的元素(aba,bac)逐一比较,发现cab不是任何元素的子串,得到最长的非公共子序列为cab,得到答案3
代码:
class Solution { public: static bool cmp(string a, string b) { return a.size()==b.size() ? a < b : a.size()> b.size(); } bool isSubString(string a,string b)//判断B是否是A的子串(A长度要比B大) { int bMatch = 0; for(int i = 0;i < a.size();i++) { if(a[i]==b[bMatch]) bMatch++; } return bMatch == b.size(); } int findLUSlength(vector<string>& strs) { int n = strs.size(); unordered_set<string> s; sort(strs.begin() ,strs.end() ,cmp); int maxlen = -1; for(int i = 0 ; i < n;i++) { if (i == n - 1 || strs[i]!=strs[i + 1] ) { unordered_set<string>::iterator it; for(it = s.begin(); it!=s.end();it++) { if(isSubString(*it,strs[i])) break; } if(it==s.end()) return strs[i].size(); } s.insert(strs[i]); } return -1; } };
分析:
在这种解法下,最好情况的时间复杂度为O(nlogn)(排序后第一个字符串为最长,并且只有一个最长),最坏时间复杂度为O(n^2)(所有字符串都是相同长度的)