Leetcode 49. 字母异位词分组

LeetCode第49题解析 给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。 示例: 输入: ["eat", "tea", "tan", "ate", "nat", "bat"] 输出: [ ["ate","eat","tea"], ["nat","tan"], ["bat"] ] 说明: 所有输入均为小写字母。 不考虑答案输出的顺序。 解法一:遍历string,排序后存放在unordered_map中,归类输出。 class Solution { public: 阅读详情

题目

给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。

示例:

输入: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],
输出:
[
[“ate”,“eat”,“tea”],
[“nat”,“tan”],
[“bat”]
]

说明:

  • 所有输入均为小写字母。
  • 不考虑答案输出的顺序。

解答

解法一:字符串排序做键

对每个字符串数组里的字符串先按字典序排序,那么具有相同字符的字符串就会映射到同一个字符串。

算法简单,最容易想到,同时也是一个此种类型的题目通用解法。

复杂度:O(nmlogm) 时间,O(nm) 空间 。

代码
class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> map = new HashMap<>();
        for(int i = 0; i < strs.length; i ++) {
            String cur = strs[i];
            char[] arr = cur.toCharArray();
            Arrays.sort(arr);
            String key = new String(arr);
            
            if(!map.containsKey(key)) {
                map.put(key, new ArrayList<>());
            }
            
            map.get(key).add(cur);
        }
    
        return new ArrayList<>(map.values());
    }
}
结果

在这里插入图片描述

解法二:计数补#

因为题目要求字符串内只会出现 a - z 的小写字母,说明所有字符都是已知的,就可以采用字符计数的方式让键唯一。

方法:

  1. 维护一个长度为 26 的数组作为计数数组。
  2. 对当前字符串计数,得到每个字符的个数。
  3. 每个位置之间增加一个 # 作为分隔符。

可以看出:拥有相同组成的字符串,字符顺序不同不会对最终的键产生影响,而是会映射到同一个键。

例如:

  • abbce - > 1#2#1#0#1#…
  • bbace - > 1#2#1#0#1#…

从执行效率上看出:此方法在大数据量,字符串长度很长的时候很占优势。但在小数据量情况下有劣势。

复杂度:O(nm) 时间,O(nm) 空间 。

代码
class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> map = new HashMap<>();
        for(int i = 0; i < strs.length; i ++) {
            int[] freq = new int[26];
            for(int j = 0; j < strs[i].length(); j ++) {
                freq[strs[i].charAt(j) - 'a'] ++;
            }
            
            StringBuilder stb = new StringBuilder("");
            for (int j = 0; j < 26; j ++) {
                stb.append(freq[j]).append("#");
            }
            
            String key = stb.toString();
            if(!map.containsKey(key)) {
                map.put(key, new ArrayList<>());
            }
            
            map.get(key).add(strs[i]);
        }
    
        return new ArrayList<>(map.values());
    }
}
结果

在这里插入图片描述

解法三:质数拆分

借鉴了一个大神的代码:传送门

主要思想是:正整数的唯一分解定理。

本质上与解法二类似:都是将相同组成但不同顺序的元素映射到同一位置。

例如:

  • abc - > 2 * 3 * 5 = 30
  • bac - > 3 * 2 * 5 = 30

缺点是乘法可能会产生溢出,优点是速度很快。这个解法属实牛逼。。。

复杂度:O(nm) 时间,O(nm) 空间 。

代码
class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        int[] primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103 };
        Map<Integer, List<String>> map = new HashMap<>();
        for(int i = 0; i < strs.length; i ++) {
            int key = 1;
            for (int j = 0; j < strs[i].length(); j ++) {
                key *= primes[strs[i].charAt(j) - 'a'];
            } 

            if(!map.containsKey(key)) {
                map.put(key, new ArrayList<>());
            }
            
            map.get(key).add(strs[i]);
        }
    
        return new ArrayList<>(map.values());
    }
}
结果

在这里插入图片描述

扩展解法:分而治之

只是想到了这种解法,但是此解法在本题并不占优势,一个尝试而已。

因而只是放在了扩展解法处,有兴趣的同学可以看看。

主要思想还是分治那一套:

  1. 确定边界返回值。
  2. 确定中点,递归左部分,再递归右部分。
  3. 融合左右两部分的结果。

效率不怎么样。分析发现可能是递归的过程有一些重复运算以及一些多余空间的开辟。

复杂度:O(mnlogn) 时间,O(nm) 空间。

代码
class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        if(strs == null || strs.length == 0) return new ArrayList<>();
        return new ArrayList<>(merge(strs, 0, strs.length - 1).values());
    }
    
    private Map<String, List<String>> merge(String[] strs, int start, int end) {
        if(start == end) {
            Map<String, List<String>> map = new HashMap<>();
            char[] chars = strs[start].toCharArray();
            Arrays.sort(chars);
            map.put(new String(chars), new ArrayList<>(Arrays.asList(strs[start])));
            return map;
        }
        
        int mid = (start + end) >>> 1;
        Map<String, List<String>> left = merge(strs, start, mid);
        Map<String, List<String>> right = merge(strs, mid + 1, end);
        
        return mergeList(left, right);
    }
    
    private Map<String, List<String>> mergeList(Map<String, List<String>> map1, Map<String, List<String>> map2) {
        for(String k1 : map1.keySet()) {
            if(map2.containsKey(k1)) {
                map2.get(k1).addAll(map1.get(k1));
            } else {
                map2.put(k1, map1.get(k1));
            }
        }
        
        return map2;
    }
}
结果

在这里插入图片描述

[LeetCode 49] 字母异位词分组 [LeetCode 49] 字母异位词分组题目描述题目分析源码难点改进小结 题目描述 给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。 示例: 输入: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”], 输出: [ [“ate”,“eat”,“tea”], [“nat”,“tan”], [“bat”] ] 说明: 所有输入均... 阅读详情

相关推荐

面试题 10.02. 变位词组

编写一种方法,对字符串数组进行排序,将所有变位词组合在一起。变位词是指字母相同,但排列不同的字符串。 注意:本题相对原题稍作修改 示例: 输入: ["eat", "tea", "tan", "ate", "nat", "bat"], 输出: [ ["ate","eat","tea"], ["nat","tan"], ["bat"] ] 说明: 所有输入均为小写字母。 不考虑答案输出的顺序。 class Solution { public: vector<vector&l...

. 470

字母异位词分组

两个字符串互为字母异位词,当且仅当两个字符串包含的字母相同。同一组字母异位词中的字符串具备相同点,可以使用相同点作为一组字母异位词的标志,使用哈希表存储每一组字母异位词,哈希表的键为一组字母异位词的标志,哈希表的值为一组字母异位词列表。 遍历每个字符串,对于每个字符串,得到该字符串所在的一组字母异位词的标志,将当前字符串加入该组字母异位词的列表中。遍历全部字符串之后,哈希表中的每个键值对即为一组字母异位词。 方法一:排序 由于互为字母异位词的两个字符串包含的字母相同,因此对两个字符串分别进行排序之后得到的字

qq_48094059的博客 994

【中等】力扣算法题解析LeetCode49:字母异位词分组

题目要求将字母异位词分组(如"eat"和"tea")。核心解法是利用哈希表,以排序后的字符串作为键,原字符串列表为值。步骤:1. 遍历字符串数组,对每个字符串排序生成统一键;2. 使用哈希表分组存储;3. 返回所有分组列表。Java实现通过Arrays.sort排序字符数组,并用computeIfAbsent简化哈希表操作。时间复杂度为O(n·mlogm),其中n为字符串数量,m为字符串最大长度。示例代码已通过力扣测试,高效完成分组。

ylumwd的博客 513

49.字母异位词分组 (详解)

这种方法的核心思想是使用哈希表,将字母异位词映射到同一个键,然后将它们分组在一起。

weixin_48751586的博客 950

Leetcode 49: 字母异位词分组

这是一道经典的哈希表与字符串操作相关的题目,考察快速分组和使用数据结构的能力。所谓字母异位词,是指由相同的字母通过重新排列形成的不同单词。题目要求将一组字符串按照字母异位词分组。,将词组按照字母异位词进行分组,返回所有分组后的结果。字母异位词具有相同的字符,只是排列顺序不同。熟练掌握解法 1 和解法 2,可以在面试中快速 AC 并展现对字符串操作和哈希表应用的理解能力!

互联网架构师笔记 1372

避坑指南:合宙Air780EG阿里云一型一密连接时,为什么你的HmacMD5加密总失败?

本文针对合宙Air780EG模组连接阿里云物联网平台时,HmacMD5签名失败的常见问题提供深度解决方案。详细剖析了签名拼接格式、密钥使用、随机数处理及编码大小写等关键陷阱,并结合STM32嵌入式开发环境,给出了串口调试、分步验证及AT指令链路的实用排错技巧,帮助开发者顺利完成一型一密动态注册。

kiwi8的博客 440

力扣(LeetCode)100题:49.字母异位词分组

本文介绍了两种解决字母异位词分组问题的方法。第一种是排序法,通过将每个字符串排序后的结果作为分组键,时间复杂度为O(nklogk)。第二种是计数法,统计每个字符出现的次数作为键,仅适用于小写字母且时间复杂度为O(nk)。两种方法都使用字典进行分组,最后返回分组后的字符串列表。相比自实现的冒泡排序,官方解法利用Python内置的sorted()函数更简洁高效。计数法则通过字符频次统计来避免排序,在特定场景下性能更优。

sweet_ran的博客 986

Nornir自动化简单介绍-网络设备信息收集

作为网工,学会通过执行脚本,可以自动化的完成日常一些设备相关配置或信息收集等工作,可以说是事半功倍。 Nornir就是这样一个自动化网络运维工具。按照官网上的说明: Nornir是用python编写的自动化框架,可与python一起使用。Nornir旨在通过提供一个纯Python框架来解决这些问题。 详细参考: Github GitHub - nornir-automation/nornir: Pluggable multi-threaded framework with inventory .

Gun&rose 7804

【LeetCode】49.字母异位词分组

0, 1],转换为元组 (1, 0, 0, 0, 1, 0, …, 0],转换为元组 (1, 0, 1, 0, 0, 0, …对于单词 “eat”,char_count 是 [1, 0, 0, 0, 1, 0, …, 0, 1],转换为元组 (1, 0, 0, 0, 1, 0, …输入: strs = [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]输出: [[“bat”],[“nat”,“tan”],[“ate”,“eat”,“tea”]]输出: [[“”]]

qq_38473254的博客 1487

ECharts 实现世界地图

效果图 源代码(仅供参考) <template> <div class="echarts"> <div class="className" id="id" style="width: 100%; height: 450px" ref="myEchart" ></div> </div> </template> <script lang="ts"> imp

EsquireY的博客 4871

超大规模AI集群跨数据中心互联:Scale-Across技术实现与部署实践

分布式系统通过将计算任务分散到多个节点协同执行,实现算力的横向扩展。其核心原理在于网络通信、数据同步和资源调度机制的技术协同。在AI基础设施领域,分布式架构能有效突破单数据中心算力瓶颈,支撑万亿参数大模型训练。特别是面对长距离传输时延和带宽稳定性挑战,需要采用RDMA、确定性网络等关键技术。Scale-Across作为分布式系统的高级形态,通过跨地域多数据中心互联,构建逻辑统一的AI算力池,为超大规模AI训练和全球推理服务提供核心支撑。本文聚焦AI集群跨数据中心互联的技术路径,涵盖全栈优化、网络自治等实践方

chouxuyi9789的博客 399

leetcode 49 字母异位词分组 C语言实现

题目 leetcode 49 给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。 示例: 输入: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”], 输出: [ [“ate”,“eat”,“tea”], [“nat”,“tan”], [“bat”] ] 说明: 所有输入均为小写字母。 不考虑答案输出的顺序。 代码 代码思路:排...

qq_42007287的博客 871

Linux之GTK系列教程

00、背上行囊1——程序员学习之道 01、背上行囊2——为什么要学习GTK 02、背上行囊3——GUI概述 03、背上行囊4——GTK简介 04、背上行囊5——GTK环境搭建( Linux ) 05、背上行囊6——GTK环境搭建( windows ) 06、踏上旅途1——一个简单的空白窗口 07、踏上旅途2——控件的添加 08、踏上旅途3——布局容器之水平布局 09、踏上旅途

每天积累一点点 2万+

力扣字符串49题-字母异位词分组java

特性HashMapTreeMap底层实现哈希表红黑树哈希表 + 双向链表键的顺序无顺序按键排序(可自定义)插入顺序或访问顺序是否允许 null 键允许 1 个不允许允许 1 个查找/插入复杂度O(1)O(log n)O(1)线程安全性否否否是否有序否有序(按键)有序(插入)

2301_81624621的博客 935

TP4056锂电池充电电路设计原理与工程实践

锂离子电池充电管理是嵌入式电源系统的核心基础技术,其本质是通过恒流恒压(CC/CV)控制策略,匹配电池电化学特性以实现安全、高效、长寿命充放电。TP4056作为典型线性充电IC,以精简外围实现预充、恒流、恒压及自动截止全周期管理,但受限于线性拓扑的热耗散特性,必须协同散热设计、电阻精度选型与PCB布局进行系统级优化。该方案广泛应用于STM32智能小车、便携传感器节点等3.7V单节锂电供电场景,兼顾成本、可靠性与工程可实施性,是入门嵌入式硬件电源设计的关键实践范例。

weixin_36064575的博客 219

基于 SoC 的卷积神经网络车牌识别系统设计(1)引言

通过 CPU 软核 IP 在纯 FPGA 平台上构建一个 AI SoC 卷积神经网络车牌识别系统,其中,缩放、填充层、卷积层、ReLU、池化层、全连接层 IP 都是 Verilog 设计的,同时集成了各种高性能的 IP。这是最具挑战性的 AI SoC 芯片设计项目,集成了 Python 卷积神经网络代码、Verilog 卷积神经网络硬件设计、ARM SoC 设计、ARM 与 FPGA 的交叉编译流程等等。这不仅是科研学习、集创竞赛、秋招求职的一个极具优势的精彩项目,也是目前最火热的芯片行业之中的一个...

新芯设计的博客 3778

Leetcode 49. 字母异位词分组

输入: strs = [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”](Python/Java/C++/Go/JS/Rust),感觉想法差不多,但是写的要比我的简洁。输出: [[“bat”],[“nat”,“tan”],[“ate”,“eat”,“tea”]]是由重新排列源单词的所有字母得到的一个新单词。可以按任意顺序返回结果列表。输入: strs = [“a”]给你一个字符串数组,请你将。看了下 灵茶山艾府 的题解。输出: [[“a”]]输出: [[“”]]

li_yizhixiaowukong的博客 800

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

力扣LeetCode Hot100:Problem:49.字母异位词分组

题目要求将字母异位词分组。字母异位词指字母相同但顺序不同的字符串。解题思路是利用排序后的字符串作为哈希表的键,原始字符串作为值进行分组。具体步骤:遍历字符串数组,对每个字符串排序后作为key存入哈希表,最后将哈希表的值转为结果列表。该方法时间复杂度O(nklogk),其中n是字符串数量,k是字符串最大长度。代码实现简洁,通过排序和哈希表高效完成分组任务。

通过输出内容提升自己 340

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

LeetCode 49.字母异位词分组

显然,如果把 aab, aba, baa 按字母从小到大排序,我们可以得到同一个字符串aab。输入: strs = [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]输出: [[“bat”],[“nat”,“tan”],[“ate”,“eat”,“tea”]]因此,可以使用哈希来分组,排序后的字符串当作key,原字符串组成的集合当作value。给你一个字符串数组,请你将 字母异位词 组合在一起。是由重新排列源单词的所有字母得到的一个新单词。输出: [[“”]]

qq_73593013的博客 1079

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

《LeetCode力扣练习》第49题 字母异位词分组 Java

《LeetCode力扣练习》第49题 字母异位词分组 Java 一、资源 题目: 给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。 示例 1: 输入: strs = [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”] 输出: [[“bat”],[“nat”,“tan”],[“ate”,“eat”,“tea”]] 示例 2: 输入: strs =

XRT_knives的博客 329

LeetCode第 49 题:字母异位词分组(C++)

49. 字母异位词分组 - 力扣(LeetCode) 核心问题在于如何(快速)判断字母异位词,很容易想到字符串匹配里面的RK算法,其实就是一种编码方式。最简单的可以将每个单词的每个字母的ascii码加起来,因为字母异位词加起来得到的和必然是相同的,但是单词太多就可能冲突:不是字母异位词加起来也可能相同,既然加不行,可以乘啊,而且不一定非要用一个整数来编码,用字符串也可以,排序就是字符串的思路。 排序 class Solution { public: vector<vector<stri

zj 1877

力扣49:字母异位词分组

在暴力解法中有以下注意事项:1.排除已经处理过的字符串,防止重复记录(我和ds均采用新建数组/集合记录处理过的字符串)2.判断字母异位词:在我的方法中,采用判断字符串中每个字符都被另一个字符串包含且两字符串长度相等来判断是否为字母异位词,该方法存在严重漏洞,详见上。关于此,ds提供了两种方法方法1// 1. 长度不同则直接排除// 2. 将字符串转为字符数组// 3. 对字符数组进行排序// 4. 比较排序后的字符数组是否相同方法2// 1. 长度不同直接排除。

2504_92344631的博客 752

LeetCode第49题_字母异位词分组

给你一个字符串数组strs,请你将组合在一起。可以按任意顺序返回结果列表。是由重新排列源单词的所有字母得到的一个新单词。

qq_40263592的博客 1391

字母异位词分组 力扣49

给你一个字符串数组,请你将组合在一起。可以按任意顺序返回结果列表。是由重新排列源单词的所有字母得到的一个新单词。

qq_65031432的博客 519
上一篇: Leetcode 44. 通配符匹配
下一篇: Leetcode 58. 最后一个单词的长度
一纸浮萍
博客等级 码龄9年 11粉丝 103原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值