【Swift】LeetCode 49. 字母异位词分组
49. 字母异位词分组
题目描述
思路 and Swift 题解
字母异位词分组是一个非常经典的字典的应用题目。首先,我们需要建立一个字典,它的 Key 是按照字典序排序的单词,Value 是一个存储字符串类型的数组。接下来我们需要对输入的字符串数组进行遍历,每次遍历时首先对字符串进行排序得到 Key,然后基于这个 Key 将当前字符串插入到对应的 Value 的数组当中,如果 Key 不存在,可能需要先对 Value 的数组进行初始化。最后,将所有 Value 数组放到一个新的数组当中,返回即可得到最终的答案。
思路非常明确,那么我们应该如何使用 Swift 来解决这道题目呢?关键点包括四个部分:
- 字典的声明,它的 Key 是
String
,Value 是[String]
; - 对字符串的排序,涉及到 Swift 内置的排序方法;
- 基于排序的结果,将当前字符串插入到 Key 索引到 Value 对应的数组当中,如果 Key 不存在,需要对 Value 的数组进行初始化;
- 将
Dictionary
当中存储的 Value 全部取出,放到一个新的Array
当中作为答案返回。
我们一步步解决上面四个关键部分。
首先,我们需要声明一个字典,在上一道题[Swift] 1. 两数之和当中我们已经学习了如何在 Swift 当中建立一个字典,此处我们如法炮制,声明并实例化一个更复杂的Dictionary
:
var mp = [String: [String]]()
其次,我们需要对输入的字符串数组进行遍历,并且每次取当前字符串进行排序得到 Key。此处就引出了 Swift 一个极其重要的知识点,那就是排序(Sort)。在 Swift 当中,对字符串排序可以使用sorted()
方法来完成。此处我重点强调方法二字,熟悉 Golang 的同学应该都知道,方法是作用于某个类型之上的,是这个类型的实例“可以调用的函数”。我们的strs
数组进行遍历,取str
为每一次遍历的元素,使用str.sorted()
可以完成对str
的排序,但返回的结果是[Character]
,此处的Character
是 Swift 当中的字符类型,还需要使用String(str)
才能够将排序的结果转为String
。至此,我们得到的结果就是一个按照字典序排序的字符串,可以用作 Key 来对mp
进行索引。
需要重点强调的是,sorted
并非String
的内置方法,而是String
遵循Sequence
协议后继承的方法。String
遵循Sequence
协议,其元素类型是Character
,因此str.sorted()
实际上调用的事Sequence.sorted()
方法,返回的类型是[Character]
。我们还没有学习到协议,但是此处的协议我个人觉得可以理解为 Golang 当中的接口,因为String
实现了Sequence
接口,因此它可以使用Sequence
接口的方法。
再次,我们需要基于排序的结果将当前的str
插入 Value 对应的数组当中。我们已经通过var key = String(str.sorted)
得到了排序后的 Key,如果 Key 已经在mp
当中了,那么直接索引其 Value 得到相应的数组再将str
插入即可;但如果此时 Key 不存在呢?显然,我们应该对 Key 对应 Value 的[String]
数组进行初始化。此处我们使用 Swift 提供给我们的语法糖,也就是在使用 Key 进行索引时,可以指定一个default
参数,来告知 Swift,如果 Key 当前不存在于 Dictionary,那么使用什么默认值来对 Key 的 Value 进行初始化:
mp[key, default: []].append(str)
最后,我们需要取Dictionary
当中所有的 Value,将其放入到新的数组当中,这个数组的类型是[[String]]
,也就是存储[String]
的数组。常规的思路是对mp
的键值对进行遍历,取 Value;但我们可以使用 Swift 的语法糖,基于mp.values
这个属性,获取mp
当中 Value 的值,得到的类型是ValueCollection
,虽然不是我们想要的Array[String]
,但是它同样遵循Sequence
协议,因此使用Array(mp.values)
即可得到mp
的 Value 组成的数组。
至此,我们解决了这道题目,完整的 Swift 题解是:
class Solution {func groupAnagrams(_ strs: [String]) -> [[String]] {var mp = [String: [String]]()for str in strs {var key = String(str.sorted())mp[key, default: [String]()].append(str)}return Array(mp.values)}
}