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. 解题思路

核心观察

  • 字母异位词的核心特征:字符相同,顺序不同。
  • 排序后,异位词会变成同一个字符串(如 eat 和 tea 排序后都是 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 简化哈希表操作,减少分支判断;懒加载方式延迟初始化结果列表,提升性能。
  • 关键技巧:异位词分组的核心是找到一个稳定的键,排序是最直接的实现方式。
相关推荐
liminla!4 分钟前
SQL 从入门到进阶:语法速查与实战练习(完整优化版)
数据库·sql·算法
维克兜率天1 小时前
【维克】指数调整:哪些股票会被“强制买入“?
人工智能·python·算法
罗西的思考2 小时前
【轻量化复刻大模型】线性注意力交互式演示
人工智能·算法·机器学习
神也畏惧菠萝2 小时前
Day08 Python流程控制从入门到上瘾:if/match/while/for四件套,从B站登录一路打到猜数字游戏
python·算法·数据存储·for·while·if·ifelse
箓维2 小时前
TCP Socket的进阶实现
网络·笔记·tcp/ip
二哈赛车手2 小时前
新人笔记---hermes定时功能设计,具体讲解以及可优化点
java·人工智能·笔记·spring·ai·typescript
揽星河..2 小时前
【C语言】分支和循环
c语言·c++·算法
星恒随风3 小时前
Linux网络编程:应用层协议究竟是什么?从网络计算器到TCP Socket抽象基类完整实现
linux·网络·笔记·tcp/ip
Fuyo_11194 小时前
C++ AVL树保姆级详解:从平衡因子到四大旋转机制
java·c++·算法