算法进阶:字母异位词分组(Group Anagrams) ----哈希表快速解决

0 阅读3分钟

问题描述:给定一个字符串列表,如: strs={ "listen", "silent", "enlist", "inlets", "evil", "live", "veil","vile", "pots", "spot", "stop", "tops", "notes", "stone", "tones","onset", "east", "eats", "seat", "teas", "pears", "parse", "spare","spear", "ate", "eat", "tea", "acre", "care", "race", "angel", "angle","glean", "rate", "tear", "tare", "rescue", "secure", "recuse", "cheaters","hectares", "teachers", "integral", "triangle", "relating", "below","elbow", "bowel", "dusty", "study", "night", "thing", "inch", "chin","bored", "robed", "state", "taste", "stressed", "desserts", "save", "vase"} 

将数组strs中互为 字母异位词 字符串 分到同一组, 组内/组间 顺序不限******

方法2 :可以使用 字典 来存储每个字符串以26字符计数(只计非零项)作为键,例如 "a2e1t1",表示字符串中有 2 个 'a',1 个 'e',1 个 't', 字符串列表 作为 。这样具有相同字符计数的字符串会被分到同一组**

任务要求******

1. 请给出以方法2实现的伪码(要求尽可能使用自然语言表述)**

*创建空字典groups(key:t)

*使用Collections.Shuffle()配合List对原数组进行洗牌乱序

*先对strs中的每个字符串s进行循环遍历:

     *创建一个长度为26的全零数组count //用来存储每个单词遍历后字母的个数

     *将字符串s转换成字符数组

     *将这个字符数组进行遍历:

          *创建一个变量index存放取出每个字符与’a’(97)相减的值 //这里需要运用Ascll值进行计算,利用每个字母都有独特的Ascll值进行一一对应的存储

     //index的范围就是0~26,对应count数组的每一个下标

         *存储相应字母的出现次数并存放到相应的数组里//数字存入数组,下标代表字母

     *在对数组count进行遍历,取出数组里面非零的数字和对应的字母

     *再用StringBuilder方法对它们进行拼接并将它存在t中

     *用排序后的拼接结果t作为分组key:

          *如果groups数组中不存在key = t,就先创建一个空列表

          *把原字符串s追加到这个空列表中

*创建一个二维数组result

*遍历字典groups的每一对(key :List):

     把List加入result

*返回结果result

 

2.  估算时间复杂度(要求提供简要具有说服力的估算过程)**

首先,循环遍历数组时间复杂度为O(n),遍历每个单词里面的每个字符时间复杂度为O(k),拼接过程中时间复杂度为O(26),HashMap的查找时间复杂度为O(1)。

所以总时间复杂度就是:O = n*(O(k)+O(26)+O(1) = O(k*n)

 

3. 给出代码实现,并进行运行输出(提供代码实现,以及运行结果输出截图)

源代码展示: image.png

运行结果展示:

image.png

4.实验总结

通过对 LeetCode 第 49 题的实现与分析,我深刻体会到了以下几点:

1. 空间换时间:使用额外的数组(空间)来统计字符,换取了查找和分组的时间效率,是算法设计中非常重要的思想。

2. 哈希表的应用:哈希表是解决分组、映射、查找类问题的万能工具,掌握其  containsKey 、 put 、 get  等核心操作至关重要。

3. 字符串处理技巧:将字符统计结果拼接为字符串作为 Key 的技巧,是解决此类问题的通用方案。

【作者说:这道题是leetcode49题的进阶版,二者思路一致,只是提供的数组不同,都是来用哈希表实现字母异位的逻辑,其中要对Ascll表有了解,认真考虑其中一一对应的关系,这很重要,是这道题的解题关键】