
本文详细介绍了在leetcode中无需对字符串进行排序,通过字符频率统计实现高效分组变位词(anagrams)的算法。文章将深入解析核心思路、代码实现细节,并对该方法的关键步骤和时间复杂度进行专业分析,帮助读者理解如何利用哈希映射优化变位词分组问题。
变位词(Anagrams)是指由相同字母但顺序不同的字符串组成的词语,例如 "eat"、"tea" 和 "ate" 互为变位词。在编程中,一个常见的问题是将一组字符串按照它们是否为变位词进行分组。传统方法通常涉及对每个字符串进行排序,然后将排序后的字符串作为哈希表的键。然而,本文将探讨一种无需排序,通过字符频率统计实现的高效方法。
该解决方案的核心思想是为每个字符串创建一个唯一的“签名”,这个签名能够代表其包含的字符种类和数量,而与字符的排列顺序无关。所有互为变位词的字符串,都将拥有相同的签名。我们将利用哈希映射(HashMap)来存储这些签名作为键,并将对应的变位词列表作为值。
初始化结果列表和哈希映射:
遍历输入字符串数组:
收集结果:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class GroupAnagrams {
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> output = new ArrayList<>();
if (strs == null || strs.length == 0) {
return output;
}
// 使用哈希映射存储频率签名到字符串列表的映射
Map<String, List<String>> outputMap = new HashMap<>();
// 遍历所有输入字符串
for (String str : strs) {
// 1. 创建字符频率数组
int[] charCounts = new int[26]; // 对应 'a' 到 'z'
// 2. 填充频率数组
for (char c : str.toCharArray()) {
charCounts[c - 'a']++;
}
// 3. 生成字符串签名(将频率数组转换为字符串)
String signature = Arrays.toString(charCounts);
// 4. 更新哈希映射
// 如果签名已存在,则将当前字符串添加到对应的列表中
// 否则,创建一个新列表并存入哈希映射
outputMap.computeIfAbsent(signature, k -> new ArrayList<>()).add(str);
// 等价于以下传统写法:
// if (outputMap.containsKey(signature)) {
// outputMap.get(signature).add(str);
// } else {
// List<String> newList = new ArrayList<>();
// newList.add(str);
// outputMap.put(signature, newList);
// }
}
// 5. 收集结果
output.addAll(outputMap.values());
return output;
}
public static void main(String[] args) {
GroupAnagrams solver = new GroupAnagrams();
String[] strs1 = {"eat", "tea", "tan", "ate", "nat", "bat"};
List<List<String>> result1 = solver.groupAnagrams(strs1);
System.out.println("Result 1: " + result1);
// 预期输出可能类似:[[bat], [nat, tan], [eat, tea, ate]] (顺序可能不同)
String[] strs2 = {""};
List<List<String>> result2 = solver.groupAnagrams(strs2);
System.out.println("Result 2: " + result2); // 预期输出:[[]] 或 [[ ]]
String[] strs3 = {"a"};
List<List<String>> result3 = solver.groupAnagrams(strs3);
System.out.println("Result 3: " + result3); // 预期输出:[[a]]
}
}我们来详细分析上述算法的时间复杂度。 假设输入字符串数组的长度为 m (即 strs.length),平均每个字符串的长度为 n。
外层循环: 算法包含一个主循环,它会遍历 strs 数组中的每一个字符串,共执行 m 次。
内层操作(针对每个字符串):
总时间复杂度计算:
最终结果收集: output.addAll(outputMap.values()) 操作会将所有列表添加到最终结果中。这个操作的复杂度取决于所有列表的总长度,最坏情况下是 O(m * n),但通常可以视为 O(m) 因为它只是收集指针。不过,它不会超过 O(m * n)。
综合来看,该算法的*时间复杂度为 O(m n)**。
通过利用字符频率数组作为哈希映射的键,我们能够高效地解决变位词分组问题,而无需对每个字符串进行耗时的排序操作。这种方法的核心在于将字符串的“结构”抽象为一个固定长度的数字序列,并将其转换为字符串作为唯一的标识符。这种思路在处理需要基于内容而非顺序进行分类的问题时非常有用。
以上就是高效分组变位词:无需排序的哈希映射方法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号