每日一题·字母异位词分组

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

示例 1:

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

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

解释:

  • 在 strs 中没有字符串可以通过重新排列来形成 "bat"
  • 字符串 "nat""tan" 是字母异位词,因为它们可以重新排列以形成彼此。
  • 字符串 "ate""eat""tea" 是字母异位词,因为它们可以重新排列以形成彼此。

示例 2:

输入: strs = [""]

输出:[[""]]

示例 3:

输入: strs = ["a"]

输出:[["a"]]

提示:

  • 1 <= strs.length <= 104
  • 0 <= strs[i].length <= 100
  • strs[i] 仅包含小写字母
java 复制代码
public List<List<String>> groupAnagrams(String[] strs) {

      // 创建一个空字典
      Map<String, List<String>> map = new HashMap<>();

      // 遍历每个单词
      for (String s : strs) {

          // 第一步:把单词拆成字符数组
          // "eat" → ['e','a','t']
          char[] chars = s.toCharArray();

          // 第二步:对字符排序
          // ['e','a','t'] → ['a','e','t']
          Arrays.sort(chars);

          // 第三步:重新拼成字符串,作为key
          // ['a','e','t'] → "aet"
          String key = new String(chars);

          // 第四步:把原单词放入对应的分组
          // 如果字典里没有"aet"这个key,就新建一个空列表
          // 如果已经有了,就直接往里加
          map.computeIfAbsent(key, k -> new ArrayList<>()).add(s);
      }

      // 把字典里所有的value(每一组列表)收集起来返回
      return new ArrayList<>(map.values());
  }

1 List ------ 有序的"列表/数组"

可以把 List 理解成一个可以自由伸缩的数组。

普通数组长度固定:

String[] arr = new String[3]; // 只能放3个,满了就不能加了

List 长度可变:

List<String> list = new ArrayList<>();

list.add("eat"); // ["eat"]

list.add("tea"); // ["eat", "tea"]

list.add("ate"); // ["eat", "tea", "ate"]

List<String> 里的 <String> 表示这个列表只装字符串。

List<List<String>> 就是列表里面装列表,比如:

\["eat", "tea", "ate"\], // 第一组 \["tan", "nat"\], // 第二组 \["bat"\] // 第三组

2 Map ------ "字典/键值对"

Map 就像一本字典,每个"词(key)"对应一个"解释(value)"。

key → value

"aet" → ["eat", "tea", "ate"]

"ant" → ["tan", "nat"]

"abt" → ["bat"]

Map<String, List<String>> map = new HashMap<>();

// 存入数据

map.put("aet", someList);

// 取出数据

map.get("aet"); // 返回 ["eat", "tea", "ate"]

Map<String, List<String>> 表示:

  • key 是 String(排序后的字符串)

  • value 是 List<String>(同一组的单词列表)

3 Map 和 HashMap 的区别

一句话总结

  • Map 是"规范/标准"(接口)

  • HashMap 是"具体实现"(实现类)

生活类比

▎ Map 就像"交通工具"这个概念

▎ HashMap 就像"汽车",是交通工具的一种具体实现

交通工具(Map 接口)

├── 汽车(HashMap) ← 最常用,速度快

├── 火车(TreeMap) ← 会自动排序

└── 自行车(LinkedHashMap) ← 保持插入顺序

接口 vs 实现类

Map 是接口,只定义了"能做什么",但不管"怎么做":

// Map 接口规定了这些方法必须有:

put(key, value) // 存数据

get(key) // 取数据

remove(key) // 删数据

containsKey(key) // 判断key是否存在

HashMap 是实现类,负责具体实现这些方法:

// HashMap 用"哈希表"这种数据结构来实现上面所有方法

为什么要这样写?

// 推荐写法:左边用接口,右边用实现类

Map<String, List<String>> map = new HashMap<>();

// 不推荐:左右都用实现类

HashMap<String, List<String>> map = new HashMap<>();

推荐左边写 Map 的好处:

将来想换一种实现,只改一处地方就够了:

// 想改成有序的?只改右边一个词

Map<String, List<String>> map = new TreeMap<>();

// 想改成保持插入顺序的?

Map<String, List<String>> map = new LinkedHashMap<>();

// 其他用到 map 的代码,一行都不用改!

如果左边写 HashMap,换实现时就要改很多地方。

相关推荐
myloveasuka2 小时前
[Java]双列集合
java
Blasit2 小时前
Qt 程序打包,运行提示找不到或无法加载平台插件 qwindows.dll
开发语言·windows·qt
lay_liu2 小时前
springboot和springframework版本依赖关系
java·spring boot·后端
C++ 老炮儿的技术栈2 小时前
c++常见配置文件格式 JSON、INI、XML、YAML 它们如何解析
xml·开发语言·c++·windows·qt·json
Elieal2 小时前
java基础面试
java·开发语言·面试
C++chaofan2 小时前
RPC框架容错机制深度解析
java·开发语言·后端·性能优化·高并发·juc·容错机制
2301_795741793 小时前
在构建企业级文生视频存储架构时,RustFS相比传统存储方案有哪些独特优势?
开发语言·python·pygame
تچ快乐杂货店يچ3 小时前
基于前后端分离的在线考试系统(微服务架构 + RBAC权限 + AI助手)
java·vue.js·spring boot·spring cloud·微服务·架构·typescript
奋斗的老史3 小时前
List和Map互转
java
是娇娇公主~3 小时前
C++ 中 std::vector 和 std::list 的区别
开发语言·c++·list