[Leetcode]522. Longest Uncommon Subsequence II

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 的不同在于这次是要在两个及以上的字符串上寻找最长非公共子串。
子串的定义是对于一个字符串,删除它的某些字符,其余字符保持顺序不变的字符串。字符串本身也是自己的一个子串。


思路
首先分析一下最长非公共子串的特征,假设有若干个字符串,其中最长非公共子串为 Sm,它的长度为 Sm.length()。从子串的定义上,我们可以知道这个 Sm 有两种可能的构成:

  1. Sm 为某一个字符串本身。
  2. Sm 为某一个小于父串长度的子串。

我们可以证明 Sm 只能为第一种情况。
首先我们假设 2 是成立的,其中 Sm 的父串是 Sf,那么说明 Sf 是某一个更长字符串的字串,所以导致 Sf 本身不能最为最长非公共子串。而由于 Sf 是某一个字符串的字串,那么 Sm 理应也是这一个字符串的子串,因为他们是包含关系,所以 Sm 是最长非公共子串跟假设 2 是矛盾的。

既然最长非公共子串只能是某个字符串本身,搜索的时候只需针对整个字符串就行。比较容易的方法是,搜索出所有可以成为非公共子串的字符串,然后在从中选出最长的,就是所需要的字符串。


代码实现

public class Solution {
    public int findLUSlength(String[] strs) {
        int longest = -1;
        for (int i = 0; i < strs.length; i++) {
            boolean isSub = true;
            for (int j = 0; j < strs.length; j++) {
                if (i != j && isSubsequence(strs[i], strs[j])) {
                    isSub = false;
                    break;
                }
            }
            if (isSub) longest = Math.max(longest, strs[i].length());
        }
        return longest;
    }

    //判断 a 是否是 b 的子串
    public boolean isSubsequence(String a, String b) {
        if (a.length() > b.length()) return false;
        if (a.equals(b)) return true;

        int position = 0;

        for (int i = 0; i < b.length(); i++) {
            if (position == a.length()) break;
            if (a.charAt(position) == b.charAt(i)) {
                position++;
            }
        }
        return position == a.length();
    }
}

这里的时间复杂度按理说是 O(n^2)的,不过在 Leetcode 上还算挺快的,我这个答案花费的时间是 13ms,可能是给的数据本身比较少。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值