Leetcode刷题(三十九)

字母异位词分组(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操作:

  1. 导入HashMap类:

    java 复制代码
    import java.util.HashMap;
  2. 创建HashMap:

    java 复制代码
    HashMap<Integer, String> map = new HashMap<>();
  3. 添加元素:

    java 复制代码
    map.put(1, "Element1");
    map.put(2, "Element2");
    map.put(3, "Element3");
  4. 访问元素:

    java 复制代码
    String value = map.get(2); // 返回 "Element2"
  5. 检查键是否存在:

    java 复制代码
    boolean exists = map.containsKey(3); // 返回 true
  6. 检查值是否存在:

    java 复制代码
    boolean valueExists = map.containsValue("Element3"); // 返回 true
  7. 删除元素:

    java 复制代码
    map.remove(3); // 移除键为3的元素
  8. 遍历HashMap:

    • 使用entrySet和增强for循环:

      java 复制代码
      for (Map.Entry<Integer, String> entry : map.entrySet()) {
          System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
      }
    • 使用keySet和增强for循环:

      java 复制代码
      for (Integer key : map.keySet()) {
          System.out.println("Key = " + key + ", Value = " + map.get(key));
      }
    • 使用forEach和Lambda表达式(Java 8+):

      java 复制代码
      map.forEach((key, value) -> System.out.println("Key = " + key + ", Value = " + value));
  9. 清空HashMap:

    java 复制代码
    map.clear(); // 移除所有元素
  10. 获取HashMap大小:

    java 复制代码
    int 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的基本操作,适用于大多数日常用途。

相关推荐
xiaobai12 34 分钟前
二叉树的遍历【C++】
开发语言·c++·算法
吱吱鼠叔29 分钟前
MATLAB数学规划:2.线性规划
算法·机器学习·matlab
声学黑洞仿真工作室36 分钟前
Matlab Delany-Bazley和Miki模型预测多孔材料吸声性能
开发语言·人工智能·算法·matlab·微信公众平台
机器学习之心40 分钟前
选址模型 | 基于混沌模拟退火粒子群优化算法的电动汽车充电站选址与定容(Matlab)
算法·选址模型
MogulNemenis1 小时前
力扣春招100题——队列
数据结构·算法·leetcode
码上一元1 小时前
【百日算法计划】:每日一题,见证成长(017)
java·算法
菜鸟求带飞_2 小时前
算法打卡:第十一章 图论part01
java·数据结构·算法
浅念同学2 小时前
算法.图论-建图/拓扑排序及其拓展
算法·图论
是小Y啦2 小时前
leetcode 106.从中序与后续遍历序列构造二叉树
数据结构·算法·leetcode
程序猿练习生2 小时前
C++速通LeetCode中等第9题-合并区间
开发语言·c++·leetcode