当前位置: 首页 > article >正文

字母异位分组力扣--49

目录

题目

思路

代码

 computeIfAbsent()


题目

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

示例 1:

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例 2:

输入: strs = [""]
输出: [[""]]
示例 3:

输入: strs = ["a"]
输出: [["a"]]

思路

理解:给你一个字符串数组,把里面的字母异位放在一起

既然是字母异位,那么将他们排序后,应该是相同的,所以当且仅当两个字符串排序后一样,这两个字符串才能分到同一组。

代码

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        // 创建一个HashMap,用于存储字母异位词分组的结果
        // 键是经过排序后的字符串,值是由对应的字母异位词组成的List<String>
        Map<String, List<String>> m = new HashMap<>();

        // 遍历输入的字符串数组strs
        for (String str : strs) {
            // 将当前字符串str转换为字符数组,方便后续进行排序操作
            char[] s = str.toCharArray();
            // 对字符数组进行排序,经过排序后,字母异位词会具有相同的字符顺序
            Arrays.sort(s);
            // 使用computeIfAbsent方法来处理键值对的添加逻辑
            // 如果以排序后的字符串(new String(s))作为键,在Map中不存在对应的键值对
            // 那么就通过后面的lambda表达式创建一个新的空的ArrayList<>()作为值,添加到Map中
            // 如果键已经存在,就返回已存在的对应的值(也就是对应的字母异位词列表)
            m.computeIfAbsent(new String(s), k -> new ArrayList<>()).add(str);
        }

        // 返回Map中所有的值(也就是各个分组好的字母异位词列表)组成的新的ArrayList
        return new ArrayList<>(m.values());
    }
}

 computeIfAbsent()

computeIfAbsent方法是Map接口提供的一个很方便的方法,它接收两个参数:第一个参数是要检查是否存在的键(在这里就是排序后的字符串,通过new String(s)创建,因为Arrays.sort操作的是字符数组,需要转换回字符串形式来作为键);第二个参数是一个Function接口实现(这里使用了 lambda 表达式k -> new ArrayList<>()),这个实现的作用是当键不存在时,用来生成对应的值(也就是创建一个新的空的ArrayList来存放属于同一组的字母异位词)

对 hashMap 中指定 key 的值进行重新计算,如果不存在这个 key,则添加到 hashMap 中。

语法: 

hashmap.computeIfAbsent(K key, Function remappingFunction)

注:hashmap 是 HashMap 类的一个对象。

  • key - 键
  • remappingFunction - 重新映射函数,用于重新计算值

如果 key 对应的 value 不存在,则使用获取 remappingFunction 重新计算后的值,并保存为该 key 的 value,否则返回 value。 

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        // 使用Java 8的Stream API来处理字符串数组strs,最后将处理结果转换为ArrayList返回
        return new ArrayList<>(
            // 首先将字符串数组strs转换为一个Stream流,这样就能利用流的各种操作来处理数据
            Arrays.stream(strs)
            // 使用collect方法进行收集操作,这里主要利用了Collectors.groupingBy来进行分组
           .collect(Collectors.groupingBy(str -> {
                // 以下是定义分组的依据,也就是分组的键的生成逻辑

                // 先将当前字符串str转换为字符数组,目的是为了能够对字符进行排序操作
                char[] array = str.toCharArray();
                // 利用Arrays.sort方法对字符数组进行排序,使得字母异位词在排序后会具有相同的字符顺序
                Arrays.sort(array);
                // 将排序后的字符数组再转换回字符串,这个字符串就作为分组的依据(类似于SQL里的group by操作中的分组依据)
                return new String(array);
            }))
            // 取出分组后的结果中所有的值(也就是各个分组好的字母异位词列表),因为collect操作返回的是一个Map,键是分组依据(排序后的字符串),值是对应的字母异位词列表
           .values()
        );
    }
}

Java8 Stream 之sorted方法 排序讲解_stream().sorted-CSDN博客 

 

对每个字符串计数得到该字符串的计数数组,对于计数数组相同的字符串,就互为异位词。
因为数组类型没有重写 hashcode() 和 equals() 方法,因此不能直接作为 HashMap 的 Key 进行聚合,那么我们就 把这个数组手动编码变成字符串就行了。
比如将 [b,a,a,a,b,c] 编码成 a3b2c1,使用编码后的字符串作为 HashMap 的 Key 进行聚合。

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        return new ArrayList<>(Arrays.stream(strs)
            .collect(Collectors.groupingBy(str -> {
                int[] counter = new int[26];
                for (int i = 0; i < str.length(); i++) {
                    counter[str.charAt(i) - 'a']++;
                }
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < 26; i++) {
                    // 这里的 if 是可省略的,但是加上 if 以后,生成的 sb 更短,后续 groupingBy 会更快。
                    if (counter[i] != 0) {
                        sb.append((char) ('a' + i));
                        sb.append(counter[i]);
                    }
                }
                return sb.toString();
            })).values());
    }
}

设 n 是数组长度,k 是字符串最大长度。


http://www.kler.cn/a/470103.html

相关文章:

  • 如何用代码提交spark任务并且获取任务权柄
  • visual studio 自动调整代码格式的问题:
  • 【51单片机】02LED流水灯实验
  • 深入刨析数据结构之排序(上)
  • 【HarmonyOS-ArkTS语言】面向对象【合集】
  • Android 性能优化:内存优化(实践篇)
  • 福建省乡镇界面数据arcgis格式shp乡镇名称和编码无偏移坐标内容测评
  • 什么是Spring Boot?深度解析其核心概念与优势
  • 从MySQL迁移到PostgreSQL的完整指南
  • Golang设计模式目录
  • CSS语言的软件开发工具
  • Easysearch Java SDK 2.0.x 使用指南(三)
  • 【微服务】5、服务保护 Sentinel
  • AWS Auto Scaling基础知识
  • 【AI日记】25.01.06
  • Ruby语言的语法
  • SVN简单使用教程
  • linux 查找redis 的配置文件 (`redis.conf`)
  • Kubernetes Gateway API-4-TCPRoute和GRPCRoute
  • 上网行为审计是什么?有什么功能?企业为什么需要上网行为审计?
  • 印象笔记08——便签功能
  • CSS学习记录24
  • Java中使用JFreeChart生成甘特图
  • 庐山派K230学习日记6 ADC
  • 深入了解 SSL/TLS 协议及其工作原理
  • 计算机网络 (28)虚拟专用网VPN