Discuss:www.cnblogs.com/grandyang/p…
Given an array of strings strs, group the anagrams together. You can return the answer in any order.
An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.
Example 1:
Input: strs = ["eat","tea","tan","ate","nat","bat"]
Output: [["bat"],["nat","tan"],["ate","eat","tea"]]
Example 2:
Input: strs = [""]
Output: [[""]]
Example 3:
Input: strs = ["a"]
Output: [["a"]]
Constraints:
-
1 <= strs.length <= 104
-
0 <= strs[i].length <= 100
-
strs[i] consists of lower-case English letters.
解法一:
这道题让我们群组给定字符串集中所有的错位词,所谓的错位词就是两个字符串中字母出现的次数都一样,只是位置不同,比如 abc,bac, cba 等它们就互为错位词,那么如何判断两者是否是错位词呢,可以发现如果把错位词的字符顺序重新排列,那么会得到相同的结果,所以重新排序是判断是否互为错位词的方法,由于错位词重新排序后都会得到相同的字符串,以此作为 key,将所有错位词都保存到字符串数组中,建立 key 和其隶属的错位词集合之间的映射。最后 Map 中的 value 集合就是我们要的结果。
class Solution {
fun groupAnagrams(strs: Array<String>): List<List<String>> {
if (strs.size == 1) {
return mutableListOf(strs.toList())
}
val result: MutableList<List<String>> = mutableListOf()
val map = mutableMapOf<String, MutableList<String>>()
strs.forEach {
// kotlin 字符串排序,需要将 string 转为 charArray,然后调用 sorted() 方法,最后再调用 joinToString("") 方法转为 string
val strArray = it.toCharArray()
val sortStr = strArray.sorted().joinToString("")
if (map.containsKey(sortStr)) {
val valueList = map[sortStr]
valueList?.add(it)
map[sortStr] = valueList ?: mutableListOf()
} else {
val valueList = mutableListOf<String>()
valueList.add(it)
map[sortStr] = valueList
}
}
map.values.forEach {
result.add(it)
}
return result
}
}
解法二:
还可以建立 key 和当前的不同的错位词集合个数之间的映射,这样可以避免最后再将 HashMap 中的集合拷贝到结果 result 中。当检测到当前的单词不在 HashMap 中,此时知道这个单词将属于一个新的错位词集合,所以将其映射为当前的错位词集合的个数,然后在 res 中新增一个空集合,这样就可以通过其映射值,直接找到新的错位词集合的位置,从而将新的单词存入结果 result 中。
class Solution {
fun groupAnagrams(strs: Array<String>): List<List<String>> {
if (strs.size == 1) {
return mutableListOf(strs.toList())
}
val result: MutableList<MutableList<String>> = mutableListOf()
val map = mutableMapOf<String, Int>()
strs.forEach {
// kotlin 字符串排序,需要将 string 转为 charArray,然后调用 sorted() 方法,最后再调用 joinToString("") 方法转为 string
val strArray = it.toCharArray()
val sortStr = strArray.sorted().joinToString("")
if (map.containsKey(sortStr)) {
val index = map[sortStr]
val valueList = result[index!!]
valueList.add(it)
} else {
val valueList = mutableListOf<String>()
valueList.add(it)
result.add(valueList)
map[sortStr] = result.lastIndex
}
}
return result
}
}
解法三:
下面这种解法没有用到排序,用一个大小为 26 的 int 数组来统计每个单词中字符出现的次数,然后将 int 数组转为一个唯一的字符串,跟字符串数组进行映射,这样就不用给字符串排序了。
class Solution {
fun groupAnagrams(strs: Array<String>): List<List<String>> {
if (strs.size == 1) {
return mutableListOf(strs.toList())
}
val result: MutableList<List<String>> = mutableListOf()
val map = mutableMapOf<String, MutableList<String>>()
strs.forEach { str ->
val count = IntArray(26)
for (i in 0 until 26) {
count[i] = 0
}
str.forEach { char ->
count[char - 'a']++
}
val key = StringBuilder()
count.withIndex().forEach forEach2@{
if (it.value == 0) {
return@forEach2
}
val char: Char = 'a'.plus(it.index)
key.append((char))
key.append(it.value)
}
val keyStr = key.toString()
if (map.containsKey(keyStr)) {
val valueList = map[keyStr]
valueList?.add(str)
map[keyStr] = valueList ?: mutableListOf()
} else {
val valueList = mutableListOf<String>()
valueList.add(str)
map[keyStr] = valueList
}
}
map.values.forEach {
result.add(it)
}
return result
}
}