LeetCode 49 字母异位词分组 | 解题思路分享

news2024/12/25 12:15:50

原题链接:49. 字母异位词分组 - 力扣(LeetCode)

题目难度:中等

题目描述

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

字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。

示例 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] 仅包含小写字母

我的解题思路

这题题目有点绕,我用大白话翻译一下,就是要把组成字母相同的字符串放在同一个列表里就行了

很显然是需要使用哈希来解题的,我们只需要将组成字母相同的字符串使用同一个kay存入到HashMap当中就可以了。只不过哈希的值只能和字符串内的字母组成相关,且不能与组成的顺序相关。

下面针对这题提供两种哈希的方法。

加与乘

首先我们把每个字符串中每个字母都当成一个数字来看。

根据我们中学(或者小学)学习的加法交换律和乘法交换律,可以知道多个数字之间相加相乘的结果是与其顺序无关的,故我们可以让字符串中的每个字母的值相乘或相加。

由于单独使用乘法或加法会出现不符合预期的情况,比如:2 * 3 = 1 * 6 = 61 + 5 = 3 + 3 = 6,这种情况下我们不希望得出相同的哈希值。

故我选择同时使用加法和乘法,可以极大的减小碰撞的概率。

核心代码如下:

long hash(String str) {
    if (str.equals("")) return -1;
    long ans = 1;
    // 先全部相乘
    for (int i = 0; i < str.length(); i++) {
        ans *= str.charAt(i);
    }
    // 再全部相加
    for (int i = 0; i < str.length(); i++) {
        ans += str.charAt(i);
    }
    return ans;
}

字母排序

当我们将字符串中的字母进行统一排序后,得到的值同样会与其组成顺序无关,且比加法乘法更加可靠。

只需要先将字符串转换成字符数组,对其进行排序后再转换成字符串,并作为key即可。

核心代码如下:

String hash(String str) {
    char[] array = str.toCharArray();
    Arrays.sort(array);
	return new String(array);
}

完整解题代码 Java

上面的哈希算法可以二选一,都能过题。

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {    
		HashMap<Long, List<String>> map = new HashMap<>();
		for (String str : strs) {
			long key = hash(str);
			List<String> list = map.getOrDefault(key, new ArrayList<>());
			list.add(str);
			map.put(key, list);
		}
		return new ArrayList<>(map.values());
	}

	long hash(String str) {
        if (str.equals("")) return -1;
		long ans = 1;
		for (int i = 0; i < str.length(); i++) {
			ans *= str.charAt(i);
		}
		for (int i = 0; i < str.length(); i++) {
			ans += str.charAt(i);
		}
		return ans;
	}
}

通过截图:

image-20230108160845773

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/150438.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分析快、易操作的数据分析工具推荐

数据分析工具发展这么多年&#xff0c;该有的技术功能都有了&#xff0c;该提高的数据分析效率、数据分析量等也都提高了&#xff0c;但很多长期奋战在一线的数据分析人员却总是抱怨数据分析工具响应慢、分析慢、越来越容易崩溃。为什么要找一款分析快、易操作的数据分析工具还…

Git入门学习笔记(10分钟速通)

一、Git概述 官网翻译&#xff1a; Git 是一个免费的开源 分布式版本控制系统&#xff0c;旨在快速高效地处理从小型项目到大型项目的所有内容。 Git易于学习&#xff0c; 体积小&#xff0c;性能快如闪电。它超越了 Subversion、CVS、Perforce 和 ClearCase 等 SCM 工具&am…

13_2、Java的IO流概述

一、Java IO原理1、I/O是Input/Output的缩写&#xff0c; I/O技术是非常实用的技术&#xff0c;用于处理设备之间的数据传输。如读/写文件&#xff0c;网络通讯等。2、Java程序中&#xff0c;对于数据的输入/输出操作以“流(stream)” 的方式进行。3、java.io包下提供了各种“流…

kaggle平台学习复习笔记 | XGBoost、LightGBM and Catboost

这里写目录1.XGBoost官方文档介绍与使用2.LightGBM官方文档介绍与使用3.CatBoost官方文档介绍与使用对比数据预处理如下&#xff0c;下文不再重复 import lightgbm as lgb import xgboost as xgb from catboost import CatBoostRegressorfrom sklearn.model_selection import …

C#入门级——泛型、泛型类、泛型接口、泛型方法和泛型委托

目录 一、泛型&#xff08;generic&#xff09; 二、为什么需要泛型类 类型膨胀 成员膨胀 使用object类 三、泛型的定义 定义泛型类 使用泛型类 泛型接口​​​​​​​ 两种泛型接口的实现方法 泛型方法 成员膨胀 使用泛型 泛型委托 Action委托——只能引用没有…

有效的需求管理,需遵循四大原则。

1、需求管理必须与需求工程活动相整合 需求管理必须与需求工程的其他活动紧密整合&#xff0c;进行需求管理一定不能脱离需求工程&#xff0c;需求工程包括了需求获取、需求分析、需求描述、需求验证、需求管理&#xff0c;因而需求管理必须与前面的几个需求阶段保持密切相关。…

2023/1/9 Vue学习笔记-5-TodoList案例

1 静态组件 App.vue <template><div class"todo-container"><div class"todo-wrap"><UserHeader/><UserList/><UserFooter/></div></div> </template> <script>import UserHeader from &qu…

【计组】FPGA和ASIC--《深入浅出计算机组成原理》(七)

课程链接&#xff1a;深入浅出计算机组成原理_组成原理_计算机基础-极客时间 目录 一、FPGA &#xff08;一&#xff09;FPGA 的解决方案步骤 1、用存储换功能实现组合逻辑 2、对于需要实现的时序逻辑电路&#xff0c;在 FPGA 里面直接放上 D 触发器&#xff0c;作为寄存…

工业清洗企业资质证书

工业清洗在美国、日本、新加坡、西欧等国发展较早&#xff0c;已经建立起专业化程度很高的化学清洗体系。我国的工业清洗发展很快&#xff0c;目前已经初步形成了新兴的清洗产业网络&#xff0c;清洗技术也已达到国际先进水平&#xff0c;具备了清洗大型设备的能力和经验。 工业…

CANoe-诊断控制台实现同一个目标ECU的物理寻址和功能寻址

接触过UDS诊断的人应该知道,诊断通信有两种方式:物理寻址和功能寻址。那什么是物理寻址和功能寻址呢? 简单点说,物理寻址是单播,功能寻址是多播。具体来说,由于UDS诊断通信的C/S模式(客户端Tester/服务器ECU),物理寻址是Tester发送的诊断请求,只有一个目标ECU回复诊…

MySQL模块

目录 1.在项目中操作数据库的步骤 2.安装与配置 mysql 模块 1.安装模块 2.配置mysql模块 3.测试模块是否正常工作 3.使用 mysql 模块操作 MySQL 数据库 查询数据&#xff1a; 插入数据&#xff1a; 快捷插入数据&#xff1a; 更新数据&#xff1a; 快捷更新数据&am…

node.js(3)--线程和进程、node简介

目录 进程和线程 Node.js 简介 历史 进程和线程 进程 负责为程序的运行提供必备的环境就相当于工厂中的车间&#xff08;专门存放代码的地方&#xff09; 线程 计算机中最小的计算单位&#xff0c;线程负责进程中的程序就相当于工厂中的工人 单线程 JS是单线程 多线程 …

ansible (第三天)

2.6 lineinfile模块 lineinfile模块&#xff0c;确保"某一行文本"存在于指定的文件中&#xff0c;或者确保从文件中删除指定的"文本"&#xff08;即确保指 定的文本不存在于文件中&#xff09;&#xff0c;还可以根据正则表达式&#xff0c;替换"某一…

测牛学堂:软件测试python基础学习之数据类型详解(一)

python数据类型详解 为什么需要数据类型呢&#xff1f; 我们人脑可以轻松的区别不同类型的数据&#xff0c;比如看到1你就知道是数字&#xff0c;但是计算机做不到。 计算机工作的过程就是完成不同的类型的计算&#xff0c;例如做数学运算&#xff0c;做文件存储&#xff0c;逻…

【技术分享】Windows平台低延迟RTMP、RTSP播放器接口设计探讨

背景我们看过了太多介绍RTSP、RTMP播放相关的技术资料&#xff0c;大多接口设计简约&#xff0c;延迟和扩展能力也受到一定的局限&#xff0c;好多开发者希望我们能从接口设计的角度&#xff0c;大概介绍下大牛直播SDK关于RTMP、RTSP播放器开发设计&#xff0c;本文以Windows平…

redis 运维讲解02

一、数据持久化 1、为什么要持久化 redis 重启后&#xff0c;redis 存在内存数据中数据丢失&#xff0c;不管之前是多少G数据&#xff0c;秒丢&#xff0c;而且无法恢复&#xff0c;数据在内存中 [root86-5-master ~]# redis-cli -p 6379 127.0.0.1:6379> MSET k1 v1 k2…

浏览器相关知识

本文主要进行浏览器相关知识的整理总结。 一、浏览器的存储 浏览器的存储包括cookie&#xff0c;session&#xff0c;LocalStorage&#xff0c;sessionStorage&#xff0c;indexedDB。 作用cookiesessionsessionStorageLocalStorageindexedDB储存时间设置或不设置默认30分钟仅…

就只有这么简单?全自动加药装置远程维护解决方案

一、行业背景说起工业生产&#xff0c;给人们的普遍印象都是浓烟&#xff0c;废水&#xff0c;环境污染。尤其是石油、化工、发电厂等一些具有大型设备的地方&#xff0c;确实常常都会有浓烟和污水产出&#xff0c;让人看了恨不得离得越远越好&#xff01;但是随着现代科技的发…

java和vue开发的电子书系统自动检测敏感词小说网站

简介 电子书系统&#xff0c;注册用户上传txt&#xff0c;系统自动检测敏感词汇并且自动生成章节。管理员审核电子书&#xff0c;管理电子书分类和用户&#xff0c;评论等。注册用户可以搜索浏览电子书&#xff0c;在线阅读和下载电子书。 演示视频&#xff1a;https://www.b…

Java设计模式-单例模式Singleton

介绍 所谓类的单例设计模式&#xff0c;就是采取一定的方法保证在整个的软件系统中&#xff0c;对某个类只能存在一个对象实例&#xff0c;并且该类只提供一个取得其对象实例的方法(静态方法)。 比如 Hibernate 的 SessionFactory&#xff0c;它充当数据存储源的代理&#xff0…