字母异位词分组(Medium)
java
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
示例 1:
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例 2:
输入: strs = [""]
输出: [[""]]
示例 3:
输入: strs = ["a"]
输出: [["a"]]
提示:
1 <= strs.length <= 104
0 <= strs[i].length <= 100
strs[i] 仅包含小写字母
Related Topics
数组
哈希表
字符串
排序
👍 1839
👎 0
思路分析
这道题的思路就是每一个词的字母组成是相同的,只是顺序不同,再进行排序之后,就可以形成相同的排序,就可以作为哈希表的key,把相同字母组成的字母异位词放在同一个key下。这里我先写出了以下的代码:
java
public List<List<String>> groupAnagrams(String[] strs) {
if (strs == null || strs.length == 0) {
return new ArrayList<>();
}
HashMap<String, List<String>> map = new HashMap<>();
for (String s : strs) {
// 将字符串转换为字符数组进行排序
char[] characters = s.toCharArray();
Arrays.sort(characters);
String sorted = new String(characters);
// 如果排序后的字符串作为键在map中不存在,则创建一个新的列表
if (!map.containsKey(sorted)) {
map.put(sorted, new ArrayList<>());
}
// 添加原始字符串到对应的列表中
map.get(sorted).add(s);
}
// 返回分组后的字符串列表
return new ArrayList<>(map.values());
}
这个代码用时7ms,击败47%,这里map.containsKey followed by map.put:这种方法首先会检查给定的键是否存在于映射中。如果不存在,就会执行map.put操作来添加一个新的键值对。这意味着如果键不存在,将会有两次哈希操作:一次是检查键是否存在,一次是实际的插入。
java
if (!map.containsKey(key)) {
map.put(key, new ArrayList<>());
}
map.get(key).add(value);
然后为了优化细节,我使用了map.getOrDefault:这种方法会一次性返回与键关联的值,如果映射不包含该键,则返回默认值。这样就只有一次哈希查找操作,即使在添加新键值对时也是如此。这可能会减少哈希表的查找次数,因为即使是在添加新元素时,getOrDefault也会一次性完成所有操作。
java
List<String> list = map.getOrDefault(key, new ArrayList<>());
list.add(value);
map.put(key, list);
代码实现
java
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<String, List<String>>();
for (String str : strs) {
char[] array = str.toCharArray();
Arrays.sort(array);
String key = new String(array);
List<String> list = map.getOrDefault(key, new ArrayList<String>());
list.add(str);
map.put(key, list);
}
return new ArrayList<List<String>>(map.values());
}
}
做题笔记
记录一些常用的哈希表操作:
在Java中,哈希表通常通过HashMap
类实现,它是java.util
包的一部分。HashMap
存储键值对,允许使用键快速查找值。以下是一些基本的HashMap
操作:
-
导入HashMap类:
javaimport java.util.HashMap;
-
创建HashMap:
javaHashMap<Integer, String> map = new HashMap<>();
-
添加元素:
javamap.put(1, "Element1"); map.put(2, "Element2"); map.put(3, "Element3");
-
访问元素:
javaString value = map.get(2); // 返回 "Element2"
-
检查键是否存在:
javaboolean exists = map.containsKey(3); // 返回 true
-
检查值是否存在:
javaboolean valueExists = map.containsValue("Element3"); // 返回 true
-
删除元素:
javamap.remove(3); // 移除键为3的元素
-
遍历HashMap:
-
使用
entrySet
和增强for循环:javafor (Map.Entry<Integer, String> entry : map.entrySet()) { System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); }
-
使用
keySet
和增强for循环:javafor (Integer key : map.keySet()) { System.out.println("Key = " + key + ", Value = " + map.get(key)); }
-
使用
forEach
和Lambda表达式(Java 8+):javamap.forEach((key, value) -> System.out.println("Key = " + key + ", Value = " + value));
-
-
清空HashMap:
javamap.clear(); // 移除所有元素
-
获取HashMap大小:
javaint size = map.size(); // 返回键值对数量
下面是一个简单的示例,展示了如何使用HashMap
:
java
import java.util.HashMap;
public class HashMapExample {
public static void main(String[] args) {
// 创建HashMap
HashMap<Integer, String> map = new HashMap<>();
// 添加键值对
map.put(1, "Apple");
map.put(2, "Banana");
map.put(3, "Cherry");
// 访问元素
String fruit = map.get(1);
System.out.println("Key 1 maps to fruit: " + fruit);
// 删除元素
map.remove(2);
// 遍历HashMap
for (Integer key : map.keySet()) {
System.out.println("Key = " + key + ", Value = " + map.get(key));
}
// 获取大小
System.out.println("Size of map: " + map.size());
// 清空HashMap
map.clear();
}
}
这个示例创建了一个HashMap
,添加了一些元素,然后遍历了这些元素,最后清空了HashMap
。这些是HashMap
的基本操作,适用于大多数日常用途。