返回

Java&C++题解与拓展——leetcode828.统计子串中的唯一字符【乘法原理】

后端

引言

leetcode828.统计子串中的唯一字符是一个有趣的问题,它考察了我们在字符串处理方面的能力。这道题要求我们计算给定字符串中子串中唯一字符的个数。

乘法原理

为了解决这个问题,我们可以使用乘法原理。乘法原理告诉我们,当有多个相互独立的事件时,这些事件同时发生的概率等于各个事件概率的乘积。

Java 题解

在 Java 中,我们可以使用以下代码来解决这个问题:

class Solution {
    /**
     * 给定一个字符串 s,统计字符串中子串中唯一字符的个数。
     *
     * @param s 输入字符串
     * @return 子串中唯一字符的个数
     */
    public int countUniqueCharacters(String s) {
        int n = s.length();
        int[] lastOccurrence = new int[26];
        Arrays.fill(lastOccurrence, -1);

        int count = 0;
        for (int i = 0; i < n; i++) {
            int index = s.charAt(i) - 'a';
            if (lastOccurrence[index] == -1) {
                count++;
            }
            lastOccurrence[index] = i;
        }

        return count;
    }
}

C++ 题解

在 C++ 中,我们可以使用以下代码来解决这个问题:

class Solution {
public:
    /**
     * 给定一个字符串 s,统计字符串中子串中唯一字符的个数。
     *
     * @param s 输入字符串
     * @return 子串中唯一字符的个数
     */
    int countUniqueCharacters(string s) {
        int n = s.size();
        vector<int> lastOccurrence(26, -1);

        int count = 0;
        for (int i = 0; i < n; i++) {
            int index = s[i] - 'a';
            if (lastOccurrence[index] == -1) {
                count++;
            }
            lastOccurrence[index] = i;
        }

        return count;
    }
};

Rust 题解

在 Rust 中,我们可以使用以下代码来解决这个问题:

struct Solution;

impl Solution {
    /**
     * 给定一个字符串 s,统计字符串中子串中唯一字符的个数。
     *
     * @param s 输入字符串
     * @return 子串中唯一字符的个数
     */
    fn count_unique_characters(s: &str) -> usize {
        let n = s.len();
        let mut last_occurrence: [isize; 26] = [-1; 26];

        let mut count = 0;
        for i in 0..n {
            let index = s.as_bytes()[i] as usize - b'a' as usize;
            if last_occurrence[index] == -1 {
                count += 1;
            }
            last_occurrence[index] = i as isize;
        }

        count
    }
}

类与方法的分析

在 Java、C++ 和 Rust 中,我们都定义了一个名为 Solution 的类,并在其中定义了一个名为 countUniqueCharacters 的方法。这个方法接收一个字符串作为参数,并返回字符串中子串中唯一字符的个数。

在 Java 和 C++ 中,lastOccurrence 数组是一个大小为 26 的数组,它存储了每个字母最后一次出现的位置。在 Rust 中,last_occurrence 数组是一个大小为 26 的数组,它存储了每个字母最后一次出现的位置,但它的类型是 isize,而不是 int

在 Java、C++ 和 Rust 中,我们都使用了一个 for 循环来遍历字符串中的每个字符。在 for 循环中,我们首先计算出当前字符在字母表中的位置,然后检查该字符最后一次出现的位置。如果该字符之前没有出现过,则我们将其计入唯一字符的个数。

扩展

我们可以对这个问题进行扩展,考虑以下问题:

  • 如果我们允许子串中包含重复的字符,那么我们如何计算字符串中子串中唯一字符的个数?
  • 如果我们给定一个字符串和一个整数 k,那么我们如何计算字符串中长度为 k 的子串中唯一字符的个数?

这些问题都可以使用乘法原理来解决。对于第一个问题,我们可以使用以下公式来计算字符串中子串中唯一字符的个数:

count = 26^n - 1

其中,n 是字符串的长度。

对于第二个问题,我们可以使用以下公式来计算字符串中长度为 k 的子串中唯一字符的个数:

count = 26^k - (26^(k-1) - 1)

其中,k 是子串的长度。

总结

leetcode828.统计子串中的唯一字符是一个有趣的问题,它考察了我们在字符串处理方面的能力。我们可以使用乘法原理来解决这个问题,也可以使用动态规划或后缀数组等其他算法。我们还可以对这个问题进行扩展,考虑更复杂的情况。