算法小练习之统计子串中的唯一字符

120 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第28天,点击查看活动详情

1、前言

每天一个算法小练习,本篇使用Java实现。

2、题目描述

  我们定义了一个函数 countUniqueChars(s) 来统计字符串 s 中的唯一字符,并返回唯一字符的个数。

  例如:s = "LEETCODE" ,则其中 "L", "T","C","O","D" 都是唯一字符,因为它们只出现一次,所以 countUniqueChars(s) = 5 。

  本题将会给你一个字符串 s ,我们需要返回 countUniqueChars(t) 的总和,其中 t 是 s 的子字符串。注意,某些子字符串可能是重复的,但你统计时也必须算上这些重复的子字符串(也就是说,你必须统计 s 的所有子字符串中的唯一字符)。

  由于答案可能非常大,请将结果 mod 10 ^ 9 + 7 后再返回。

2.1、示例1

输入: s = "ABC"

输出: 10

解释: 所有可能的子串为:"A","B","C","AB","BC" 和 "ABC"。
     其中,每一个子串都由独特字符构成。
     所以其长度总和为:1 + 1 + 1 + 2 + 2 + 3 = 10

2.2、示例2

输入: s = "ABA"

输出: 8

解释: 除了 countUniqueChars("ABA") = 1 之外,其余与示例 1 相同。

2.3、示例3

输入:s = "LEETCODE"

输出:92

3、解题思路

记录重复出现的字符串前一个的下标,以及前前一个下标。每次以当前下标为结尾的子串个数可以从以前面一个为下标的个数中转移,也就是说以前面字符为下标 + (i - endArr[s.charAt(i) - 'A']),再减去(endArr[s.charAt(i) - 'A'] - startArr[s.charAt(i) - 'A'])。因为前面是字符串多加了个当前字符所以加一,而它再往前一个就需要减1,因此后面操作减去(endArr[s.charAt(i) - 'A'] - startArr[s.charAt(i) - 'A']),其余不变。

3.1、实现代码

public int uniqueLetterString(String str) {
    int[] startArr = new int[26];
    int[] endArr = new int[26];
    Arrays.fill(startArr , - 1);
    Arrays.fill(endArr , - 1);
    int sum = 0;
    int res = 0;
    for (int i = 0; i < str.length(); i++) {
        int index = str.charAt(i) - 'A';
        sum += (i - endArr[index]);
        sum -= (endArr[index] - startArr[index]);
        if (endArr[index] == -1){
            endArr[index] = i;
        }else {
            startArr[index] = endArr[index];
            endArr[index] = i;
        }
        res += sum;
    }
    return res % 1000000007;
}

3.2、执行结果

image.png

好了、本期就先介绍到这里,有什么需要交流的,大家可以随时私信我。😊