[LeetCode] (medium) 522. Longest Uncommon Subsequence II

博客围绕LeetCode上最长不常见子序列问题展开,介绍了不常见子序列的定义,即一个字符串的子序列且不是其他字符串的子序列。先分析两字符串情况,后探讨多个字符串时需相互比较,给出了相应解法及代码,时间复杂度能击败100%提交。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://leetcode.com/problems/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.

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.

Example 1:

Input: "aba", "cdc", "eae"
Output: 3

Note:

  1. All the given strings' lengths will not exceed 10.
  2. The length of the given list will be in the range of [2, 50].

https://leetcode.com/problems/longest-uncommon-subsequence-ii/discuss/235912/C%2B%2B-solution-beats-100-with-the-detail-explanation

First of all, you have to understand uncommon subsequences. The question takes me a while to realize it. Indeed, there're many tricky solutions with one line codes by comparison with lengths of two strings. But Why? If you've got it already, you can directly neglect the next paragraph.

 

Given that A is a subsequence of B. B can be as A by deleting some characters in order. for example, cd is a subsequence of caeedc. As a result of deleting aee and last c, you can get a string cd. According to the definition of uncommon subsequence, it is defined as the subsequence of one of these strings and this subsequence should not be any subsequence. Therefore, dcc is an uncommon subsequence of caeedc.That is to say, you cannot alter caeedc into dcc by deleting characters in order.

 

Let's go back to LUS-One first. You want to find out the longest uncommon subsequence between two strings. Given that A and B. If A is a subsequence of B, and B is a subsequence of A. The answer would be -1, because A is not an uncommon subsequence of B, and B is not the uncommon subsequence of A neither. If A is an uncommon subsequence of B, the length of the uncommon subsequence is the length of A, and vice versa, you can get the length of B when B is an uncommon subsequence of A. Therefore, you can get one line code in C++.

 

return a==b ? -1 : max(a.size(), b.size());

 

Okay, Let's move toward LUS-Two. Based on I (One) question, you have to compare with all strings mutually in II (Two). First, we can define the LCS function withO(n), n depicts max(a.length(), b.length()) .

 

bool LCS(const string& a, const string& b) {
	if (b.size() < a.size()) return false;
	int i = 0;
    for(auto ch: b) {
		if(i < a.size() && a[i] == ch) i++;
    }
    return i == a.size();
}

 

Then, we can compare with all strings with O(m²), m represents the size of vector<string>. We iterate all strings mutually, and if the strings are uncommon subsequence, we record the lengths. The time complexity of the solution is O(m²logn), and beats 100% submissions with 8ms. The code shows as follows:

 

class Solution {
public:
    int findLUSlength(vector<string>& strs) {
        if (strs.empty()) return -1;
        int rst = -1;
        for(auto i = 0; i < strs.size(); i++) {
            int j = 0;
            for(j=0; j < strs.size(); j++) {
                if(i==j) continue;
                if(LCS(strs[i], strs[j])) break;  // strs[j] is a subsequence of strs[i]
            }
            // strs[i] is not any subsequence of the other strings.
            if(j==strs.size()) rst = max(rst, static_cast<int>(strs[i].size()));
        }
        return rst;
    }
    // iff a is a subsequence of b
    bool LCS(const string& a, const string& b) {
        if (b.size() < a.size()) return false;
        int i = 0;
        for(auto ch: b) {
            if(i < a.size() && a[i] == ch) i++;
        }
        return i == a.size();
    }
};

 

This is not a perfect solution right now, but it is quite easy to understand, even though the question gets plenty of negative votes not to be worth solving.


class Solution {
public:
    int findLUSlength(vector<string>& strs) {
        sort(strs.begin(), strs.end(), [](string &st1, string &st2) -> bool {
            return st1.size() > st2.size();
        });
        
        for(int i = 0; i < strs.size(); ++i){
            bool flag = true;
            for(int j = 0; j < strs.size() && strs[j].size() >= strs[i].size(); ++j){
                if(j == i) continue;
                if(issubstr(strs[i], strs[j])){
                    flag = false;
                    break;
                }
            }
            
            if(flag) return strs[i].size();
        }
        
        return -1;
    }
    
    bool issubstr(string &st1, string &st2){
        if(st1.size() > st2.size()) return false;
        int i = 0;
        for(char c : st2){
            if(i < st1.size() && st1[i] == c) ++i;
        }
        if(i == st1.size()) return true;
        else return false;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值