小U的相似字符串 | 豆包MarsCode AI刷题

做题笔记:字符串相似对的计数

问题分析

本题给定了一组字符串,我们需要统计其中有多少对字符串是相似的。根据题意,两个字符串相似当且仅当它们的每个字母出现的次数完全相同。换句话说,两个字符串的字符频率是一样的,只是字符的顺序可能不同。

例如:

  • "abcbd" 和 "dbcba" 是相似的,因为它们的字符频率分别为:a:1, b:2, c:1, d:1
  • "abb" 和 "aab" 不相似,因为它们的字符频率不同。

通过该题,我们可以将每个字符串转化为一个字符频率的表示,再比较这些频率是否相同。对于一组字符串中相似字符串对的统计,最直接的做法是将所有字符串的字符频率计算出来,然后统计频率相同的字符串对数。

解题思路

  1. 字符频率的表示:我们可以将每个字符串的字符频率表示为一个字符串。由于题目中的字符串仅包含小写字母,因此我们可以为每个字符串创建一个长度为26的数组(代表26个小写字母的频率)。将每个字母的频率填入对应的位置,最后将这个数组转化为字符串,作为这个字符串的"特征值"或"键"。
  2. 频率统计:我们需要统计每个频率字符串出现的次数。对于每个字符串,使用字符频率数组生成的"特征值"作为键,将其在一个哈希表中出现的次数进行统计。
  3. 计算相似字符串对数 :一旦我们得到每种字符频率字符串的出现次数,就可以根据组合数公式计算相似字符串对的数量。如果某种字符频率的字符串出现了 count 次,那么相似的字符串对数为 count * (count - 1) / 2,这是从 count 个字符串中选取两个字符串的组合数。
  4. 最终输出结果:累加所有频率字符串的相似对数,即为最终结果。

代码实现

java 复制代码
import java.util.HashMap;
import java.util.Map;

public class Solution {
    public static int solution(int n, String[] strings) {
        Map<String, Integer> frequencyMap = new HashMap<>();

        // 统计每个字符串的字符频率
        for (String str : strings) {
            int[] charCount = new int[26]; // 26个字母的频率数组
            for (char c : str.toCharArray()) {
                charCount[c - 'a']++;
            }
            // 生成频率字符串
            StringBuilder frequencyKey = new StringBuilder();
            for (int count : charCount) {
                frequencyKey.append(count).append('#'); // 用 '#' 分隔不同字符的频率
            }
            frequencyMap.put(frequencyKey.toString(), frequencyMap.getOrDefault(frequencyKey.toString(), 0) + 1);
        }

        // 计算相似字符串对的数量
        int similarPairs = 0;
        for (int count : frequencyMap.values()) {
            if (count > 1) {
                similarPairs += (count * (count - 1)) / 2; // 组合数
            }
        }

        return similarPairs;
    }
}

代码解析

  1. frequencyMap:这是一个哈希表,键为字符串的字符频率表示(即频率字符串),值为该频率字符串出现的次数。
  2. 字符频率统计 :对于每个字符串,我们使用一个长度为26的数组 charCount 来记录字符串中每个字母的出现次数。然后,使用一个 StringBuilder 将这些频率转化为一个字符串,并将该字符串作为键存入哈希表。
  3. 计算相似对数 :通过遍历哈希表中的每个键,计算该键对应的频率字符串出现的次数 count,如果 count 大于1,则可以从这些字符串中选择两两组合的方式计算相似对数,即使用组合数公式 count * (count - 1) / 2
  4. 返回结果:最后返回所有相似字符串对的总数。

时间复杂度分析

  1. 字符频率计算 :对于每个字符串,我们需要遍历它的字符并更新字符频率。每个字符串的长度为 L,总共有 n 个字符串,因此字符频率计算的时间复杂度是 O(n * L)
  2. 哈希表更新 :对于每个字符串,更新哈希表中的频率字符串的时间复杂度是常数时间 O(1),因此总的哈希表更新时间复杂度是 O(n)
  3. 计算相似对数 :遍历哈希表中的所有频率字符串,最坏情况下我们可能会有 n 个不同的频率字符串,因此时间复杂度是 O(n)

综上所述,整体的时间复杂度是 O(n * L),其中 n 是字符串的个数,L 是字符串的最大长度。

代码测试

考虑几个测试样例:

  • 样例1:输入 n = 7, strings = ["abcbd", "dbcba", "abcd", "abcd", "adbc", "aa", "aa"],输出 5

    • 字符频率统计:{"a:1, b:2, c:1, d:1": 2, "a:1, b:1, c:1, d:1": 1, "a:2": 2}
    • 相似对数为 5。
  • 样例2:输入 n = 3, strings = ["aab", "bba", "baa"],输出 1

    • 字符频率统计:{"a:2, b:1": 3}
    • 相似对数为 1。
  • 样例3:输入 n = 5, strings = ["abc", "def", "ghi", "jkl", "mno"],输出 0

    • 字符频率统计:所有字符频率都是唯一的,无相似对。
相关推荐
用户19700900815385 天前
实现一个TodoList | 青训营 x 豆包MarsCode技术训练营
青训营笔记
Grin25 天前
寻找最大葫芦 | 豆包MarsCode AI刷题
青训营笔记
用户7337855092591 个月前
后端笔记 | go语言进阶与依赖管理
青训营笔记
用户705615332611 个月前
刷题心得(三)| 豆包MarsCode AI刷题
青训营笔记
Damony1 个月前
Chain of Thought(CoT)和Tree of Thoughts(ToT)| 豆包MarsCode AI刷题
青训营笔记
Find5 个月前
MaxKB 集成langchain + Vue + PostgreSQL 的 本地大模型+本地知识库 构建私有大模型 | MarsCode AI刷题
青训营笔记
理tan王子5 个月前
伴学笔记 AI刷题 14.数组元素之和最小化 | 豆包MarsCode AI刷题
青训营笔记
理tan王子5 个月前
伴学笔记 AI刷题 25.DNA序列编辑距离 | 豆包MarsCode AI刷题
青训营笔记
理tan王子5 个月前
伴学笔记 AI刷题 9.超市里的货物架调整 | 豆包MarsCode AI刷题
青训营笔记