LeetCode题练习与总结:字母异位词分组

104 篇文章 0 订阅
64 篇文章 0 订阅

一、题目描述

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

示例 1:

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

示例 2:

输入: strs = [""]
输出: [[""]]

示例 3:

输入: strs = ["a"]
输出: [["a"]]

提示:

  • 1 <= strs.length <= 10^4
  • 0 <= strs[i].length <= 100
  • strs[i] 仅包含小写字母

二、解题思路

  1. 理解问题:我们需要将一组字符串按照字母异位词进行分组。字母异位词指的是字母的排列不同,但是字母的种类和数量完全相同。

  2. 创建映射:我们可以使用一个Map来存储每个字符串与其对应的异位词列表。Map的键是一个字符串,表示一个字符串数组,这个数组中的每个元素都是原字符串的一个异位词。Map的值是一个List,存储所有异位词。

  3. 处理字符串:对于输入数组中的每个字符串,我们需要进行排序,以便将相同的字母异位词放在一起。例如,"eat"、"tea"和"ate"排序后都变成"aet"。

  4. 填充映射:将排序后的字符串作为Map的键,将原始字符串添加到对应的List中。

  5. 返回结果:最后,我们需要遍历Map的值,将所有的List收集到一个List中,并返回这个List。

三、具体代码

import java.util.*;

public class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        // 创建一个Map来存储排序后的字符串和对应的异位词列表
        Map<String, List<String>> map = new HashMap<>();
        
        // 遍历所有的字符串
        for (String str : strs) {
            // 对字符串进行排序,以便将异位词放在一起
            char[] charArray = str.toCharArray();
            Arrays.sort(charArray);
            String sortedStr = new String(charArray);
            
            // 将排序后的字符串作为键,原始字符串添加到对应的List中
            map.computeIfAbsent(sortedStr, k -> new ArrayList<>()).add(str);
        }
        
        // 收集所有的异位词列表
        List<List<String>> result = new ArrayList<>();
        result.addAll(map.values());
        
        return result;
    }
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 对于每个字符串,我们都需要进行一次排序操作。字符串排序的时间复杂度是 O(n log n),其中 n 是字符串的长度。由于字符串的最大长度为 100,这个操作对整个算法的影响较小。
  • 我们还需要遍历所有的字符串,这个操作的时间复杂度是 O(m),其中 m 是字符串数组的长度。
  • Map 的 computeIfAbsent 方法在大多数情况下是 O(1),但在最坏情况下(例如当Map的负载因子达到一定阈值时需要扩容)可能会达到 O(n)。
  • 最后,我们将Map中的所有List添加到结果List中,这个操作的时间复杂度是 O(k),其中 k 是Map中元素的数量。
  • 综上所述,总的时间复杂度是 O(m * n log n + m * n + k)。由于 m 和 n 都可能非常大,我们可以简化为 O(m * n log n),这是因为排序操作通常比其他操作更耗时。
2. 空间复杂度
  • Map 存储了每个排序后的字符串及其对应的原始字符串列表。在最坏的情况下,每个字符串都是唯一的异位词,这意味着 Map 中将有 m 个键值对,每个键值对占用 O(n) 的空间来存储原始字符串列表。
  • 结果List 存储了所有的异位词列表,其空间复杂度为 O(k)。
  • 因此,总的空间复杂度是 O(m * n + k),其中 m 是字符串数组的长度,n 是字符串的平均长度,k 是Map中元素的数量。在最坏的情况下,k 可能等于 m,因此空间复杂度可以简化为 O(m * n)。

五、总结知识点

1. Java集合框架(Collections Framework):

  • HashMap: 一个基于键值对的数据结构,允许使用一个对象作为键来存储和检索另一个对象。在这个例子中,HashMap用于存储排序后的字符串作为键,以及对应的原始字符串列表作为值。
  • ArrayList: 一个动态数组的实现,用于存储有序集合中的元素。在这个例子中,ArrayList用作HashMap的值,来存储具有相同排序字符串的原始字符串列表。

2. 字符串操作:

  • toCharArray(): 这个方法将字符串转换为字符数组。
  • Arrays.sort(): 这是一个静态方法,用于对数组进行排序。在这个例子中,它被用来对字符串中的字符进行排序,以便将异位词分组。
  • new String(charArray): 这个构造函数用于从字符数组创建一个新的字符串。

3. Map操作:

  • computeIfAbsent(): 这是一个Map接口中的方法,用于在Map中查找一个键对应的值。如果键不存在,它会使用提供的函数来计算值,并将其放入Map中。这个方法在这个例子中用于创建新的ArrayList(如果还没有为排序后的字符串创建过),然后将原始字符串添加到这个列表中。

4. 排序算法:

  • 代码中使用了Java的内置排序方法(由Arrays.sort()提供),这是一种基于归并排序的算法,其时间复杂度通常为O(n log n)。

5. List操作:

  • addAll(): 这是一个List接口中的方法,用于将一个集合中的所有元素添加到另一个集合中。在这个例子中,它被用来将Map中的所有异位词列表添加到结果List中。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

  • 34
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一直学习永不止步

谢谢您的鼓励,我会再接再厉的!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值