LeetCode 补拙笔记 日期:2026.06.07 题目:49. 字母异位词分组

LeetCode 补拙笔记

0. 前言

  • 日期:2026.06.07
  • 题目:49. 字母异位词分组
  • 难度:中等
  • 标签:字符串、哈希表、排序

1. 题目理解

问题描述

给定一个字符串数组,将字母异位词组合在一起。字母异位词指的是由相同字母以不同顺序排列而成的单词。

示例

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

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

2. 解题思路

核心观察

  • 字母异位词的核心特征:字符相同,顺序不同
  • 排序后,异位词会变成同一个字符串(如 eattea 排序后都是 aet),因此可以用排序后的字符串作为哈希表的键。

算法步骤

  1. 遍历所有字符串;
  2. 对每个字符串排序,生成唯一键;
  3. 以排序后的字符串为键,将原字符串加入哈希表对应的列表;
  4. 最后取出哈希表中所有的值,即为分组结果。

3. 代码实现

java 复制代码
package lc0_lc99.lc49;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        int index =0;
        List<List<String>> res = new ArrayList<>();
        HashMap<String, Integer> map = new HashMap<>();
        for (int i = 0; i < strs.length; i++) {
            String s = strs[i];
            int n = method1(s, map);
            if (n != -1) {
                res.get(n).add(s);
            }
            else {
                ArrayList<String > ss = new ArrayList<>();
                ss.add(s);
                res.add(ss);
                char[] chars = s.toCharArray();
                Arrays.sort(chars);
                String s1 = String.valueOf(chars);
                map.put(s1,index++);
            }
        }

        return res;
    }

    private int method1(String s, HashMap<String, Integer> map) {
        char[] chars = s.toCharArray();
        Arrays.sort(chars);
        String s1 = String.valueOf(chars);
        if (map.containsKey(s1)) {
            return map.get(s1);
        }
        return -1;
    }
}

4. 代码优化说明

java 复制代码
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
    // 使用匿名内部类继承AbstractList实现懒加载
    return new AbstractList<>() {
        List<List<String>> list = null;

        // 懒加载初始化方法,仅在首次访问时执行
        private void init() {
            if (list != null) {
                return;
            }
            Map<String, List<String>> map = new HashMap<>();
            for (String str : strs) {
                // 排序生成异位词的统一key
                char[] chars = str.toCharArray();
                Arrays.sort(chars);
                String key = new String(chars);
                // computeIfAbsent:key不存在时创建新列表,存在时直接返回列表
                map.computeIfAbsent(key, k -> new ArrayList<>()).add(str);
            }
            list = new ArrayList<>(map.values());
        }

        // 重写get方法,访问前触发初始化
        @Override
        public List<String> get(int index) {
            init();
            return list.get(index);
        }

        // 重写size方法,访问前触发初始化
        @Override
        public int size() {
            init();
            return list.size();
        }
    };
}
}

5. 复杂度分析

  • 时间复杂度 :O(nklog⁡k)O(nk\log k)O(nklogk),其中 nnn 是字符串数量,kkk 是字符串平均长度。每个字符串排序的时间复杂度为 O(klog⁡k)O(k\log k)O(klogk)。
  • 空间复杂度 :O(nk)O(nk)O(nk),哈希表存储所有字符串,总空间为 nnn 个长度为 kkk 的字符串。

6. 总结

  • 核心:排序+哈希表,用排序后的字符串作为异位词的唯一标识。
  • 优化点:使用 computeIfAbsent 简化哈希表操作,减少分支判断;懒加载方式延迟初始化结果列表,提升性能。
  • 关键技巧:异位词分组的核心是找到一个稳定的键,排序是最直接的实现方式。
相关推荐
问心无愧05131 小时前
ctf show web入门101
android·前端·笔记
装不满的克莱因瓶1 小时前
了解不同机器学习模型的分类
人工智能·python·算法·机器学习·ai·分类·数据挖掘
QiLinkOS1 小时前
合肥气链科技有限公司本质总结
c++·科技·算法·gitee·开源
AOwhisky1 小时前
MySQL 学习笔记(第五期):用户管理与权限控制
linux·运维·数据库·笔记·学习·mysql
2501_931803751 小时前
线性筛(欧拉筛):从原理到应用
算法
ysu_03141 小时前
leetcode数据结构与算法5~7:链表双指针与二级指针
数据结构·学习·算法·leetcode·链表
ouliten1 小时前
C++笔记:偏现代C++日志系统
c++·笔记
小欣加油1 小时前
leetcode542 01矩阵
数据结构·c++·算法·leetcode·矩阵·bfs
JdSnE27zv1 小时前
EF Code First学习笔记:数据库创建
数据库·笔记·学习