LeetCode 题目 49:字母异位词分组 5种算法实现与典型应用案例【python】

简介: LeetCode 题目 49:字母异位词分组 5种算法实现与典型应用案例【python】

作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。

会一些的技术:数据分析、算法、SQL、大数据相关、python

欢迎加入社区:码上找工作

作者专栏每日更新:

LeetCode解锁1000题: 打怪升级之旅

python数据分析可视化:企业实战案例

备注说明:方便大家阅读,统一使用python,带必要注释,公众号 数据分析螺丝钉 一起打怪升级

题目描述

首先,字母异位词是指由相同字母以不同顺序组成的单词或短语。例如,“ate”, “eat”, 和 “tea” 是互为字母异位词的单词,因为它们都包含相同的字母 ‘a’、‘e’ 和 ‘t’,只是字母的顺序不同。

你需要编写一个函数来:

输入:一个字符串数组 strs,其中包含一系列单词。

处理:将这些单词分组,使得每一组内的单词都互为字母异位词。

输出:分组后的单词列表,这是一个列表的列表,其中每个子列表包含一组互为字母异位词的单词。

输入格式
  • strs:一个字符串数组。
输出格式
  • 返回一个列表,每个子列表包含所有的字母异位词。

示例

示例 1
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"], ["nat", "tan"], ["ate", "eat", "tea"]]

解释:

单词 “eat”, “tea”, 和 “ate” 互为字母异位词,因此它们被分为一组。

单词 “tan” 和 “nat” 互为字母异位词,所以它们被分为另一组。

单词 “bat” 自身独立成组,因为没有其他单词与其构成字母异位词。

示例 2
输入: strs = [""]
输出: [[""]]

算法分析

方法一:排序数组分类

解题步骤
  1. 创建哈希表:使用字典来组织异位词,键是排序后的单词,值是原单词的列表。
  2. 遍历字符串数组:对每个字符串排序,将排序后的字符串作为键,原字符串加入对应的列表。
  3. 输出结果:将哈希表的所有值转为列表输出。
完整的规范代码
def groupAnagrams(strs):
    """
    使用哈希表根据排序后的字符串分类字母异位词
    :param strs: List[str], 输入的字符串数组
    :return: List[List[str]], 分组后的字母异位词列表
    """
    anagram_map = {}
    for s in strs:
        sorted_s = ''.join(sorted(s))
        if sorted_s not in anagram_map:
            anagram_map[sorted_s] = [s]
        else:
            anagram_map[sorted_s].append(s)
    return list(anagram_map.values())
# 示例调用
print(groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"]))
算法分析
  • 时间复杂度:(O(nk \log k)),其中 (n) 是字符串的数量,(k) 是字符串的最大长度。
  • 空间复杂度:(O(nk)),用于存储哈希表。

方法二:计数作为键

解题步骤
  1. 使用计数数组:对每个字符串,使用长度为26的计数数组(针对26个英文字母)来统计每个字母的出现次数。
  2. 转换为元组作为键:将计数数组转换为元组,用作哈希表的键。
  3. 分类存储:根据计数元组将字符串归类到对应的列表。
完整的规范代码
def groupAnagrams(strs):
    """
    使用字符计数数组作为哈希表键来分类字母异位词
    :param strs: List[str], 输入的字符串数组
    :return: List[List[str]], 分组后的字母异位词列表
    """
    anagram_map = {}
    for s in strs:
        count = [0] * 26  # 对应26个英文字母
        for char in s:
            count[ord(char) - ord('a')] += 1
        count_tuple = tuple(count)
        if count_tuple not in anagram_map:
            anagram_map[count_tuple] = [s]
        else:
            anagram_map[count_tuple].append(s)
    return list(anagram_map.values())
# 示例调用
print(groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"]))
算法分析
  • 时间复杂度:(O(nk)),其中 (n) 是字符串数量,(k) 是字符串的最大长度。
  • 空间复杂度:(O(nk)),用于存储哈希表。

方法三:质数乘积作为键

解题步骤
  1. 使用质数:将26个英文字母映射到26个质数上。
  2. 计算哈希值:每个字符串通过其字符对应的质数的乘积得到一个

哈希值。

3. 分类存储:根据哈希值将字符串归类到对应的列表。

完整的规范代码
def groupAnagrams(strs):
    """
    使用质数乘积作为哈希键来分类字母异位词
    :param strs: List[str], 输入的字符串数组
    :return: List[List[str]], 分组后的字母异位词列表
    """
    primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101]
    anagram_map = {}
    for s in strs:
        key = 1
        for char in s:
            key *= primes[ord(char) - ord('a')]
        if key not in anagram_map:
            anagram_map[key] = [s]
        else:
            anagram_map[key].append(s)
    return list(anagram_map.values())
# 示例调用
print(groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"]))
算法分析
  • 时间复杂度:(O(nk)),其中 (n) 是字符串的数量,(k) 是字符串的平均长度。
  • 空间复杂度:(O(nk)),主要用于存储输出结果。

方法四:改进的计数法

解题步骤
  1. 优化计数表示:与方法二相同,但使用字符串表示计数数组,减少转换开销。
  2. 使用字符串键:直接将计数数组转换成字符串形式,作为哈希键使用。
完整的规范代码
def groupAnagrams(strs):
    """
    使用改进的计数法(字符串键)分类字母异位词
    :param strs: List[str], 输入的字符串数组
    :return: List[List[str]], 分组后的字母异位词列表
    """
    anagram_map = {}
    for s in strs:
        count = [0] * 26
        for char in s:
            count[ord(char) - ord('a')] += 1
        key = '#'.join(map(str, count))  # 将计数数组转换为字符串形式
        if key not in anagram_map:
            anagram_map[key] = [s]
        else:
            anagram_map[key].append(s)
    return list(anagram_map.values())
# 示例调用
print(groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"]))
算法分析
  • 时间复杂度:(O(nk)),其中 (n) 是字符串的数量,(k) 是字符串的平均长度。
  • 空间复杂度:(O(nk)),用于存储哈希表。

方法五:排序后哈希

解题步骤
  1. 直接排序:每个字符串排序,排序后的字符串作为键。
  2. 哈希表存储:相同排序结果的字符串归为一组。
完整的规范代码
def groupAnagrams(strs):
    """
    使用字符串排序后作为哈希键来分类字母异位词
    :param strs: List[str], 输入的字符串数组
    :return: List[List[str]], 分组后的字母异位词列表
    """
    anagram_map = {}
    for s in strs:
        key = ''.join(sorted(s))
        if key not in anagram_map:
            anagram_map[key] = [s]
        else:
            anagram_map[key].append(s)
    return list(anagram_map.values())
# 示例调用
print(groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"]))
算法分析
  • 时间复杂度:(O(nk \log k)),其中 (n) 是字符串的数量,(k) 是字符串的最大长度。
  • 空间复杂度:(O(nk)\

),用于存储哈希表和结果列表。

不同算法的优劣势对比

特征 方法一:排序数组分类 方法二:计数作为键 方法三:质数乘积作为键 方法四:改进的计数法 方法五:排序后哈希
时间复杂度 (O(nk \log k)) (O(nk)) (O(nk)) (O(nk)) (O(nk \log k))
空间复杂度 (O(nk)) (O(nk)) (O(nk)) (O(nk)) (O(nk))
优势 - 实现简单
- 易于理解
- 更快的运行时间
- 无需排序
- 唯一性好,冲突概率低
- 空间效率高
- 计数转字符串快
- 空间效率更优
- 代码简洁
- 实现直观
劣势 - 排序开销大 - 计数数组转换开销 - 质数映射复杂度高 - 字符串操作开销 - 排序时间开销大
适用场景 - 简单场景
- 教学演示
- 性能要求较高场景 - 避免哈希冲突场景 - 大数据量优化 - 代码简洁优先场景

在选择合适的方法时,应考虑实际的需求和问题规模。例如,对于需要快速处理的应用场景,可以选择计数作为键的方法;而对于需要代码简洁且易于理解的场景,则可以考虑排序后哈希的方法。对于需要避免哈希表冲突的复杂应用,质数乘积作为键提供了一个有趣的解决方案。

典型应用

字母异位词分组的应用示例覆盖了多个领域,包括数据处理、安全领域、文本分析等。这些应用不仅展示了算法的实用性,而且提供了对其在现实世界中的实际应用的洞见。

应用示例一:搜索引擎优化

场景描述

在搜索引擎技术中,快速识别并聚类含有相同字母的关键词(异位词)可以显著提高搜索结果的相关性和质量。例如,用户搜索“listen”的结果应该能够包含与“silent”相关的内容,因为它们是字母异位词。

实现步骤
  1. 关键词预处理:对搜索引擎数据库中的所有关键词进行异位词分组处理,创建一个从排序关键词到原始关键词列表的映射。
  2. 查询优化
  • 当用户提交一个搜索查询时,对查询词进行排序。
  • 查找排序后与之匹配的所有异位词组,将这些词包括在搜索结果中。
代码示例
def preprocess_keywords(keywords):
    anagram_map = {}
    for keyword in keywords:
        sorted_keyword = ''.join(sorted(keyword))
        if sorted_keyword not in anagram_map:
            anagram_map[sorted_keyword] = [keyword]
        else:
            anagram_map[sorted_keyword].append(keyword)
    return anagram_map
def search(query, anagram_map):
    sorted_query = ''.join(sorted(query))
    return anagram_map.get(sorted_query, [])
# 示例关键词库和搜索
keywords = ["listen", "silent", "enlist", "google", "gooegl"]
anagram_map = preprocess_keywords(keywords)
print(search("tinsel", anagram_map))  # 输出: ['listen', 'silent', 'enlist'

应用示例二:安全审计

场景描述

在安全审计中,确保没有敏感词被无意识地使用是非常重要的。通过将敏感词库扩展为包含所有可能的字母异位词,可以增强审计过程的全面性,例如防止某些敏感信息在加密通讯中被隐藏。

实现步骤
  1. 敏感词库扩展:将所有敏感词及其异位词形式都纳入审计字典。
  2. 通讯内容检查:审查通过的所有消息都要检查是否包含这些敏感词或其异位词。
代码示例
def expand_sensitive_words(words):
    expanded_dict = {}
    for word in words:
        permutations = groupAnagrams([word])
        for perm in permutations[0]:
            expanded_dict[perm] = True
    return expanded_dict
def audit_communication(message, sensitive_dict):
    words = message.split()
    for word in words:
        if ''.join(sorted(word)) in sensitive_dict:
            return False
    return True
# 审计示例
sensitive_words = ["example", "word"]
sensitive_dict = expand_sensitive_words(sensitive_words)
message = "This is a simple wodr and an eaxmple."
print(audit_communication(message, sensitive_dict))  # 输出: False

算法优势与挑战

这些应用示例突出显示了字母异位词分组算法的多功能性和实用性。利用这种算法可以在不同场景下提供精确、高效的解决方案。然而,这也带来了一些挑战,如处理大数据集时的性能优化,以及在多语言环境中的应用适配等。通过不断优化算法实现和扩展其应用范围,可以更好地满足现实世界复杂多变的需求。


欢迎关注微信公众号 数据分析螺丝钉

相关文章
|
6月前
|
机器学习/深度学习 人工智能 算法
猫狗宠物识别系统Python+TensorFlow+人工智能+深度学习+卷积网络算法
宠物识别系统使用Python和TensorFlow搭建卷积神经网络,基于37种常见猫狗数据集训练高精度模型,并保存为h5格式。通过Django框架搭建Web平台,用户上传宠物图片即可识别其名称,提供便捷的宠物识别服务。
653 55
|
5月前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的眼疾识别系统实现~人工智能+卷积网络算法
眼疾识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了4种常见的眼疾图像数据集(白内障、糖尿病性视网膜病变、青光眼和正常眼睛) 再使用通过搭建的算法模型对数据集进行训练得到一个识别精度较高的模型,然后保存为为本地h5格式文件。最后使用Django框架搭建了一个Web网页平台可视化操作界面,实现用户上传一张眼疾图片识别其名称。
380 5
基于Python深度学习的眼疾识别系统实现~人工智能+卷积网络算法
|
25天前
|
存储 监控 算法
企业数据泄露风险防控视域下 Python 布隆过滤器算法的应用研究 —— 怎样防止员工私下接单,监控为例
本文探讨了布隆过滤器在企业员工行为监控中的应用。布隆过滤器是一种高效概率数据结构,具有空间复杂度低、查询速度快的特点,适用于大规模数据过滤场景。文章分析了其在网络访问监控和通讯内容筛查中的实践价值,并通过Python实现示例展示其技术优势。同时,文中指出布隆过滤器存在误判风险,需在准确性和资源消耗间权衡。最后强调构建多维度监控体系的重要性,结合技术与管理手段保障企业运营安全。
48 10
|
1月前
|
算法 Python
Apriori算法的Python实例演示
经过运行,你会看到一些集合出现,每个集合的支持度也会给出。这些集合就是你想要的,经常一起被购买的商品组合。不要忘记,`min_support`参数将决定频繁项集的数量和大小,你可以根据自己的需要进行更改。
88 18
|
1月前
|
存储 机器学习/深度学习 算法
论上网限制软件中 Python 动态衰减权重算法于行为管控领域的创新性应用
在网络安全与行为管理的学术语境中,上网限制软件面临着精准识别并管控用户不合规网络请求的复杂任务。传统的基于静态规则库或固定阈值的策略,在实践中暴露出较高的误判率与较差的动态适应性。本研究引入一种基于 “动态衰减权重算法” 的优化策略,融合时间序列分析与权重衰减机制,旨在显著提升上网限制软件的实时决策效能。
43 2
|
2月前
|
存储 监控 算法
员工电脑监控场景下 Python 红黑树算法的深度解析
在当代企业管理范式中,员工电脑监控业已成为一种广泛采用的策略性手段,其核心目标在于维护企业信息安全、提升工作效能并确保合规性。借助对员工电脑操作的实时监测机制,企业能够敏锐洞察潜在风险,诸如数据泄露、恶意软件侵袭等威胁。而员工电脑监控系统的高效运作,高度依赖于底层的数据结构与算法架构。本文旨在深入探究红黑树(Red - Black Tree)这一数据结构在员工电脑监控领域的应用,并通过 Python 代码实例详尽阐释其实现机制。
72 7
|
3月前
|
人工智能 编解码 算法
如何在Python下实现摄像头|屏幕|AI视觉算法数据的RTMP直播推送
本文详细讲解了在Python环境下使用大牛直播SDK实现RTMP推流的过程。从技术背景到代码实现,涵盖Python生态优势、AI视觉算法应用、RTMP稳定性及跨平台支持等内容。通过丰富功能如音频编码、视频编码、实时预览等,结合实际代码示例,为开发者提供完整指南。同时探讨C接口转换Python时的注意事项,包括数据类型映射、内存管理、回调函数等关键点。最终总结Python在RTMP推流与AI视觉算法结合中的重要性与前景,为行业应用带来便利与革新。
162 5
|
6月前
|
存储 缓存 监控
局域网屏幕监控系统中的Python数据结构与算法实现
局域网屏幕监控系统用于实时捕获和监控局域网内多台设备的屏幕内容。本文介绍了一种基于Python双端队列(Deque)实现的滑动窗口数据缓存机制,以处理连续的屏幕帧数据流。通过固定长度的窗口,高效增删数据,确保低延迟显示和存储。该算法适用于数据压缩、异常检测等场景,保证系统在高负载下稳定运行。 本文转载自:https://www.vipshare.com
175 66
|
4月前
|
算法 Serverless 数据处理
从集思录可转债数据探秘:Python与C++实现的移动平均算法应用
本文探讨了如何利用移动平均算法分析集思录提供的可转债数据,帮助投资者把握价格趋势。通过Python和C++两种编程语言实现简单移动平均(SMA),展示了数据处理的具体方法。Python代码借助`pandas`库轻松计算5日SMA,而C++代码则通过高效的数据处理展示了SMA的计算过程。集思录平台提供了详尽且及时的可转债数据,助力投资者结合算法与社区讨论,做出更明智的投资决策。掌握这些工具和技术,有助于在复杂多变的金融市场中挖掘更多价值。
121 12
|
4月前
|
算法 安全 网络安全
基于 Python 的布隆过滤器算法在内网行为管理中的应用探究
在复杂多变的网络环境中,内网行为管理至关重要。本文介绍布隆过滤器(Bloom Filter),一种高效的空间节省型概率数据结构,用于判断元素是否存在于集合中。通过多个哈希函数映射到位数组,实现快速访问控制。Python代码示例展示了如何构建和使用布隆过滤器,有效提升企业内网安全性和资源管理效率。
82 9

热门文章

最新文章

推荐镜像

更多