[LeetCode] 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.

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].

 

這道題是之前那道Longest Uncommon Subsequence I的拓展,那道題因為只有兩個字符串為大家所不屑。那么這道題有多個字符串,這次大家滿足了吧。令我吃驚的是,這次的OJ異常的大度,連暴力搜索的解法也讓過,那么還等什么,無腦暴力破解吧。遍歷所有的字符串,對於每個遍歷到的字符串,再和所有的其他的字符串比較,看是不是某一個字符串的子序列,如果都不是的話,那么當前字符串就是一個非共同子序列,用其長度來更新結果res,參見代碼如下:

 

解法一:

class Solution {
public:
    int findLUSlength(vector<string>& strs) {
        int res = -1, j = 0, n = strs.size();
        for (int i = 0; i < n; ++i) {
            for (j = 0; j < n; ++j) {
                if (i == j) continue;
                if (checkSubs(strs[i], strs[j])) break;
            }
            if (j == n) res = max(res, (int)strs[i].size());
        }
        return res;
    }
    int checkSubs(string subs, string str) {
        int i = 0;
        for (char c : str) {
            if (c == subs[i]) ++i;
            if (i == subs.size()) break;
        } 
        return i == subs.size();
    }
};

 

下面這種解法使用一些博主能想到的優化手段,首先我們給字符串按長度來排序,將長度大的放到前面,這樣我們如果找到了非共同子序列,那么直接返回其長度即可,因為當前找到的肯定是最長的。然后我們用一個集合來記錄已經遍歷過的字符串,利用集合的去重復特性,這樣在有大量的重復字符串的時候可以提高效率,然后我們開始遍歷字符串,對於當前遍歷到的字符串,我們和集合中的所有字符串相比,看其是否是某個的子序列,如果都不是,說明當前的就是最長的非共同子序列。注意如果當前的字符串是集合中某個字符串的子序列,那么直接break出來,不用再和其他的比較了,這樣在集合中有大量的字符串時可以提高效率,最后別忘了將遍歷過的字符串加入集合中,參見代碼如下:

 

解法二:

class Solution {
public:
    int findLUSlength(vector<string>& strs) {
        int n = strs.size();
        unordered_set<string> s;
        sort(strs.begin(), strs.end(), [](string a, string b){
            if (a.size() == b.size()) return a > b;
            return a.size() > b.size();
        });
        for (int i = 0; i < n; ++i) {
            if (i == n - 1 || strs[i] != strs[i + 1]) {
                bool found = true;
                for (auto a : s) {
                    int j = 0;
                    for (char c : a) {
                        if (c == strs[i][j]) ++j;
                        if (j == strs[i].size()) break;
                    }
                    if (j == strs[i].size()) {
                        found = false;
                        break;
                    }
                }
                if (found) return strs[i].size();
            }
            s.insert(strs[i]);
        }
        return -1;
    }
};

 

類似題目:

Longest Uncommon Subsequence I

 

參考資料:

https://discuss.leetcode.com/topic/85033/checking-subsequence-without-hashing

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM