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

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

示例 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 String3; // 只能放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,换实现时就要改很多地方。

相关推荐
维吉斯蔡2 小时前
【VS Code / Cursor】文件夹右键快捷打开与文件类型自动关联
开发语言·程序人生·学习方法
蓝斯4973 小时前
[原创]《C#高级GDI+实战:从零开发一个流程图》第章:增加贝塞尔曲线,上、下、左、右连接点
java·c#·流程图
前端工作日常3 小时前
我学习到的Java 的 Service 分层:itf 和 impl 到底是什么?
java·后端
都叫我大帅哥4 小时前
Spring @Transactional 注解完全指南
java·spring
Java成神之路-4 小时前
G1 垃圾回收器 :SATB + TAMS核心机制深度解析
java·jvm
前端工作日常4 小时前
我学习到的JIT即时编译与机器码缓存失效
java·后端
带刺的坐椅4 小时前
Solon 的 10 种 HTTP 服务器:改一行依赖,换一个引擎
java·solon·jetty·undertow·mcp-server·htttp
luj_17685 小时前
星火科技助力边远地区防病攻坚
c语言·开发语言·c++·经验分享·算法
always_TT5 小时前
【Python 日志记录:logging 模块入门】
开发语言·python·php
xcLeigh5 小时前
Go入门:变量声明的五种方式详解
java·开发语言·golang