【问题标题】:Number of substrings with unique letters具有唯一字母的子串数
【发布时间】:2020-12-17 17:14:28
【问题描述】:

我有一个字符串,现在想计算子字符串的最小数量,这样子字符串中的字母应该只出现一次。

示例:

Input : cycle
Output : 2

解释:

Possible substrings are : ('cy', 'cle') or ('c', 'ycle')

示例:

Input : aaaa
Output : 4

解释:

Possible substrings are : ('a', 'a', 'a', 'a')

我能够获取所有可能的子字符串,但我无法理解如何实现此任务的解决方案:

static int distinctSubString(String S) {
    int count = 0;
    int n = S.length();
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j <= n; j++) {
            String s = S.substring(i, j);
            System.out.println(s);
        }
    }
    return count;
}

【问题讨论】:

  • 我将通过逐个添加字符来构造子字符串,直到您达到当前子字符串中已经存在的字符,此时我将开始一个新子字符串并增加计数>
  • 我建议在计算可能的子字符串数量时,计算该特定子字符串中唯一字母的数量,如果它等于子字符串的长度,就可以了。如果该特定 n 的每个子字符串都可以,则可以将这些子字符串添加到输出
  • @Aaron,如果我按照这种方式,我将只能得到('cy', 'cle') 的权利。我不会得到('c', 'ycle')
  • 你是对的,但我不相信如果你只需要返回最少量的子字符串,这是有问题的。如果您需要显示所有可能的最小长度子字符串,您可能希望在您的问题中更清楚
  • 那么子字符串必须覆盖所有字符串?

标签: java algorithm


【解决方案1】:

您应该注意,这可以贪婪地完成。每当您遇到一个角色时,可以将其添加到先前的分区中,也可以开始一个新的分区。如果两者都可能,那么您始终可以添加到前一个分区而不更改任何其他内容,因此答案不会因此变得更糟。因此,解决方案是跨字符运行,并在可以执行时将字符添加到分区中。这个解是渐近最优的。请注意,如果您的字符属于特定范围,则使用数组而不是 HashSet 可以显着提高性能。

static int distinctSubString(String S) {
    int count = (S.isEmpty()) ? 0 : 1;
    S = S.toLowerCase();
    HashSet<Character> letters = new HashSet<Character>();
    for (int i = 0; i < S.length(); i++) {
        if (letters.contains(S.charAt(i))) {
            letters.clear();
            count++;
        }
        letters.add(S.charAt(i));
    }
    return count;
}

【讨论】:

  • 抱歉,您的代码中有很多编译问题
  • 忘记了java没有字符串的方括号语法,修复了代码。此外,需要导入 java.util.HashSet 来编译它;
  • 我在您的回答中添加了(我认为是解决方法)希望您不介意,顺便说一句 +1 不错的回答
  • 我添加的应该可以解决这个问题
  • @dreamcrash 我错过了你的初始化为 1 修复了一个关闭的问题。我不确定是否对空字符串进行测试是否有意义(您的修复给出了空字符串的 1 个子字符串,我的给出了 0)
猜你喜欢
  • 1970-01-01
  • 2012-06-18
  • 2020-04-10
  • 2020-11-23
  • 1970-01-01
  • 1970-01-01
  • 2014-07-08
  • 2017-04-06
  • 2011-08-18
相关资源
最近更新 更多