力扣LeetCode: 2506 统计相似字符串对的数目

server/2025/2/23 18:08:23/

题目:

给你一个下标从 0 开始的字符串数组 words 。

如果两个字符串由相同的字符组成,则认为这两个字符串 相似 。

  • 例如,"abca" 和 "cba" 相似,因为它们都由字符 'a''b''c' 组成。
  • 然而,"abacba" 和 "bcfd" 不相似,因为它们不是相同字符组成的。

请你找出满足字符串 words[i]  words[j] 相似的下标对 (i, j) ,并返回下标对的数目,其中 0 <= i < j <= words.length - 1 。

示例 1:

输入:words = ["aba","aabb","abcd","bac","aabc"]
输出:2
解释:共有 2 对满足条件:
- i = 0 且 j = 1 :words[0] 和 words[1] 只由字符 'a' 和 'b' 组成。 
- i = 3 且 j = 4 :words[3] 和 words[4] 只由字符 'a'、'b' 和 'c' 。 

示例 2:

输入:words = ["aabb","ab","ba"]
输出:3
解释:共有 3 对满足条件:
- i = 0 且 j = 1 :words[0] 和 words[1] 只由字符 'a' 和 'b' 组成。 
- i = 0 且 j = 2 :words[0] 和 words[2] 只由字符 'a' 和 'b' 组成。 
- i = 1 且 j = 2 :words[1] 和 words[2] 只由字符 'a' 和 'b' 组成。 

示例 3:

输入:words = ["nba","cba","dba"]
输出:0
解释:不存在满足条件的下标对,返回 0 。

提示:

  • 1 <= words.length <= 100
  • 1 <= words[i].length <= 100
  • words[i] 仅由小写英文字母组成

解法:

解决思路

  1. 提取字符集合

    • 对于每个字符串,提取其中包含的字符种类(去重)。

    • 例如,"aba" 的字符集合是 {'a', 'b'}"aabb" 的字符集合也是 {'a', 'b'}

  2. 比较字符集合

    • 如果两个字符串的字符集合相同,则它们相似。

    • 例如,"aba" 和 "aabb" 的字符集合都是 {'a', 'b'},因此它们相似。

  3. 统计相似对数

    • 对于所有字符串,统计具有相同字符集合的字符串数量。

    • 如果有 k 个字符串具有相同的字符集合,则这些字符串之间可以形成 C(k, 2) 对相似对(即从 k 个字符串中选 2 个的组合数)。


实现步骤

  1. 提取字符集合

    • 对每个字符串,将其字符去重并排序,生成一个唯一的标识符(例如,将字符集合转换为字符串)。

    • 例如,"aba" 的字符集合是 {'a', 'b'},可以转换为字符串 "ab"

  2. 统计字符集合的出现次数

    • 使用哈希表(unordered_map)记录每个字符集合的出现次数。

    • 例如,"ab" 出现 2 次,"abc" 出现 1 次。

  3. 计算相似对数

    • 对于哈希表中的每个字符集合,如果有 k 个字符串具有相同的字符集合,则这些字符串之间可以形成 k * (k - 1) / 2 对相似对。

    • 将所有字符集合的相似对数累加,得到最终结果。


代码实现

class Solution {
public:int similarPairs(vector<string>& words) {unordered_map<string, int> countMap;// 遍历每个字符串,提取字符集合并统计for (const string& word : words) {string charSet = getCharSet(word);countMap[charSet]++;}int result = 0;// 计算满足条件的下标对数量for (const auto& pair : countMap) {int k = pair.second;if (k >= 2) {result += k * (k - 1) / 2;}}return result;}private:string getCharSet(const string& word) {vector<char> chars(word.begin(), word.end());sort(chars.begin(), chars.end());chars.erase(unique(chars.begin(), chars.end()), chars.end());return string(chars.begin(), chars.end());}
};

代码详细解释

  1. getCharSet 函数

    • 输入:一个字符串 word

    • 输出:该字符串的字符集合(去重并排序后的字符串)。

    • 实现步骤:

      • 将字符串转换为字符数组 chars

      • 对字符数组排序(sort)。

      • 去重(unique 和 erase)。

      • 将字符数组转换为字符串并返回。

    示例

    • 输入:"aba"

    • 输出:"ab"

  2. similarPairs 函数

    • 输入:字符串数组 words

    • 输出:满足条件的下标对数量。

    • 实现步骤:

      • 遍历每个字符串,调用 getCharSet 获取字符集合。

      • 使用哈希表 countMap 统计每个字符集合的出现次数。

      • 遍历哈希表,计算每个字符集合的相似对数,并累加到结果中。

    示例

    • 输入:["aba", "aabb", "abcd", "bac", "aabc"]

    • 哈希表内容:{"ab": 2, "abcd": 1, "abc": 2}

    • 计算结果:C(2, 2) + C(2, 2) = 1 + 1 = 2


复杂度分析

  1. 时间复杂度

    • 提取字符集合:对于每个字符串,排序和去重的复杂度为 O(m log m),其中 m 是字符串的平均长度。

    • 统计哈希表:遍历所有字符串的复杂度为 O(n),其中 n 是字符串的数量。

    • 计算相似对数:遍历哈希表的复杂度为 O(n)

    • 总时间复杂度:O(n * m log m)

  2. 空间复杂度

    • 哈希表 countMap 的空间复杂度为 O(n)

    • 字符集合的空间复杂度为 O(m)

    • 总空间复杂度:O(n * m)


示例运行

示例 1:

输入:words = ["aba", "aabb", "abcd", "bac", "aabc"]

  1. 提取字符集合:

    • "aba" -> "ab"

    • "aabb" -> "ab"

    • "abcd" -> "abcd"

    • "bac" -> "abc"

    • "aabc" -> "abc"

  2. 统计哈希表:

    • {"ab": 2, "abcd": 1, "abc": 2}

  3. 计算相似对数:

    • "ab" 出现 2 次 -> C(2, 2) = 1

    • "abc" 出现 2 次 -> C(2, 2) = 1

    • 总相似对数:1 + 1 = 2

输出:2


示例 2:

输入:words = ["aabb", "ab", "ba"]

  1. 提取字符集合:

    • "aabb" -> "ab"

    • "ab" -> "ab"

    • "ba" -> "ab"

  2. 统计哈希表:

    • {"ab": 3}

  3. 计算相似对数:

    • "ab" 出现 3 次 -> C(3, 2) = 3

    • 总相似对数:3

输出:3


示例 3:

输入:words = ["nba", "cba", "dba"]

  1. 提取字符集合:

    • "nba" -> "abn"

    • "cba" -> "abc"

    • "dba" -> "abd"

  2. 统计哈希表:

    • {"abn": 1, "abc": 1, "abd": 1}

  3. 计算相似对数:

    • 每个字符集合只出现 1 次,无法形成相似对。

    • 总相似对数:0

输出:0


总结

通过提取字符集合、统计哈希表,并计算组合数,我们可以高效地解决这个问题。代码的时间复杂度和空间复杂度都在合理范围内,能够处理题目中的最大输入规模。


http://www.ppmy.cn/server/170175.html

相关文章

AMBA-CHI协议详解(十八)

AMBA-CHI协议详解&#xff08;一&#xff09;- Introduction AMBA-CHI协议详解&#xff08;二&#xff09;- Channel fields / Read transactions AMBA-CHI协议详解&#xff08;三&#xff09;- Write transactions AMBA-CHI协议详解&#xff08;四&#xff09;- Other transac…

微信小程序-二维码绘制

wxml <view bindlongtap"saveQrcode"><!-- 二维码 --><view style"position: absolute;background-color: #FFFAEC;width: 100%;height: 100vh;"><canvas canvas-id"myQrcode" style"width: 200px; height: 200px;ba…

源码方式安装llama.cpp及调试

llama.cpp源码方式安装和调试配置 构建和编译 注意这里是cuda&#xff0c;且要开启debug模式 cmake -B build -DGGML_CUDAON -DCMAKE_BUILD_TYPEDebug cmake --build build --config Debug正在编译&#xff1a; 配置launch.json用于调式&#xff1a; 要根据自己的环境路径…

Vue.js 与 Ajax(Axios)的深入探索

Vue.js 与 Ajax(Axios)的深入探索 引言 在当前的前端开发领域,Vue.js 已经成为了最受欢迎的 JavaScript 框架之一。它以其简洁的语法、高效的性能和强大的生态系统获得了广泛的应用。而在与后端服务交互时,Ajax 技术是不可或缺的。本文将深入探讨 Vue.js 与 Ajax(Axios)…

AWS-SAA中文版题库

一家公司收集多大洲城市的温度、湿度和大气压数据。该公司每天从每个站点收集的平均数据量为500GB。每个站点都有高速互联网连接。该公司希望尽快将所有这些全球站点的数据聚合到一个AmazonS3存储桶中。解决方案必须将操作复杂性降至最低。哪种解决方案满足这些要求&#xff1f…

win32汇编环境,窗口程序中使用菜单示例二

;运行效果 ;win32汇编环境,窗口程序中使用菜单示例二 ;最基本的应用&#xff0c;通过将资源里的菜单载入窗口的模式&#xff0c;添加菜单及点击后响应的操作方法 ;直接抄进RadAsm可编译运行。重要部分加备注。 ;下面为asm文件 ;>>>>>>>>>>>&g…

Python在实际工作中的运用-Excel数据统计和数据分析

说起Excel数据统计和数据分析&#xff0c;这也是Excel的强项&#xff0c;那为什么还要用python呢&#xff01;我认为主要原因还是和使用场景有关&#xff0c;在需要进行重复性的、自动化的出具数据统计和分析报表方面&#xff0c;采用python来完成还是比较适合的。下面我们就用…

android 网络防护 手机网络安全怎么防

手机也会受到网络攻击吗&#xff1f;是的。没错。手机目前已经成为攻击者最爱的目标。不只是它更容易受到攻击&#xff0c;而是他缺乏安全的保护。 企业&#xff0c;政府的基础设施虽然可以让攻击者获利很多&#xff0c;但是攻击难度很大&#xff0c;这些组织都有专业的团队在处…