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

相关推荐
a东方青1 小时前
蓝桥杯 2024 C++国 B最小字符串
c++·职场和发展·蓝桥杯
北上ing1 小时前
算法练习:19.JZ29 顺时针打印矩阵
算法·leetcode·矩阵
.格子衫.2 小时前
真题卷001——算法备赛
算法
XiaoyaoCarter2 小时前
每日一道leetcode
c++·算法·leetcode·职场和发展·二分查找·深度优先·前缀树
Hygge-star2 小时前
【数据结构】二分查找5.12
java·数据结构·程序人生·算法·学习方法
June`4 小时前
专题二:二叉树的深度搜索(二叉树剪枝)
c++·算法·深度优先·剪枝
好吃的肘子5 小时前
Elasticsearch架构原理
开发语言·算法·elasticsearch·架构·jenkins
胡耀超5 小时前
霍夫圆变换全面解析(OpenCV)
人工智能·python·opencv·算法·计算机视觉·数据挖掘·数据安全
软行5 小时前
LeetCode 每日一题 3341. 到达最后一个房间的最少时间 I + II
数据结构·c++·算法·leetcode·职场和发展
nlog3n5 小时前
Go语言交替打印问题及多种实现方法
开发语言·算法·golang