当前位置: 首页 > news >正文

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

一、题目描述

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

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

示例 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中。

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

相关文章:

  • Java类与对象:从概念到实践的全景解析!
  • 在 Linux 中通过 SSH 执行远程命令时,无法自动加载环境变量(已解决)
  • 【Leetcode】top 100 栈
  • SpringBoot -- 整合SpringMVC
  • JavaScript如何制作轮播图
  • 程序员开发技术整理(持续整理中)
  • LeetCode 2908.元素和最小的山形三元组 I:贪心(两次遍历)——双O(n)复杂度
  • kafka部署之简单密钥
  • 【设计模式】工厂方法模式详解
  • 输出1到10的阶乘--C语言
  • linux之自主shell编写
  • 【MATLAB源码-第22期】基于matlab的手动实现的(未调用内置函数)CRC循环码编码译码仿真。
  • 关于MD5加密
  • uniapp实现列表动态添加
  • 软考105-上午题-【结构化开发】-系统文档
  • CentOS7简单部署NFS
  • Docker下部署自己的LNMP工作环境
  • javascript 哈希表
  • Less 日常用法
  • Linux后台研发超实用命令总结
  • Nacos系列:Nacos的Java SDK使用
  • Python实现BT种子转化为磁力链接【实战】
  • sessionStorage和localStorage
  • SpringBoot 实战 (三) | 配置文件详解
  • TCP拥塞控制
  • vagrant 添加本地 box 安装 laravel homestead
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • Vue组件定义
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • 仿天猫超市收藏抛物线动画工具库
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 学习使用ExpressJS 4.0中的新Router
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • ​香农与信息论三大定律
  • #WEB前端(HTML属性)
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (9)STL算法之逆转旋转
  • (SpringBoot)第二章:Spring创建和使用
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (算法)前K大的和
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • *p=a是把a的值赋给p,p=a是把a的地址赋给p。
  • .bat批处理(二):%0 %1——给批处理脚本传递参数
  • .describe() python_Python-Win32com-Excel
  • .net core 6 集成和使用 mongodb
  • .NET 药厂业务系统 CPU爆高分析
  • .NET开发不可不知、不可不用的辅助类(一)
  • .skip() 和 .only() 的使用
  • ?php echo ?,?php echo Hello world!;?
  • [2023年]-hadoop面试真题(一)
  • [AIR] NativeExtension在IOS下的开发实例 --- IOS项目的创建 (一)