时间复杂度:,n为字符串数目,k为字符串的最大长度
解题思路
对每个字符串的字母排序,若是字母异位词那么一定会排序后结果相同,组成一组集合。再利用map的key去重性,将排序后的字符串作为key且字母异位词集合作为value存储到map中,实现题目要求的字母异位词分组。
AC代码
func groupAnagrams(strs []string) [][]string {
record:=map[string][]string{}
//遍历所有字符串
for _,str:=range strs{
bytes:=[]byte(str)//string类型转为byte数组类型,方便之后的排序
sort.Slice(bytes,func(i,j int)bool{return bytes[i]<bytes[j]})//用sort.Slice实现对字符串字母的排序
sortedStr:=string(bytes)//将byte数组类型的字符串转回string类型
record[sortedStr]=append(record[sortedStr],str)//value数组添加排序前的字符串
}
//存放结果的二维切片,长度为map中key 的数目
res:=make([][]string,0,len(record))
//遍历map的所有value保存结果
for _,v:=range record{
res=append(res,v)
}
return res
}
感悟
有时可通过排序来解决问题,特别是这种涉及到排列组合的题目。
这题思路很简单,但用Go语言写起来也有不少的坑,如string转byte数组、sort.Slice的用法……
扩充
sort.Slice()的用法
sort.Slice()要有两个参数,第一个是要排序的变量,第二个是规定排序方式的函数。
sort.Slice(bytes,func(i,j int)bool{return bytes[i]<bytes[j]})
以上文提到的这句代码为例,第二个参数的形参i和j可以理解为当前正在比较的两个元素的索引,返回值是一个bool类型的变量,至于比较依据,那就是需要在函数体中确定。这段代码是从小到大升序排列,所以返回的是是否下标为i的元素小于下标为j的元素;若是想要降序排列,将小于号改为大于号即可。
我们还可以比较结构体数组实现特定的排序要求:
type myDataType struct {
name string
age int
}
func main() {
mySlice := make([]myDataType, 0)
mySlice = append(mySlice, myDataType{"张三", 42})
mySlice = append(mySlice, myDataType{"李四", 28})
mySlice = append(mySlice, myDataType{"王五", 38})
fmt.Println(mySlice)
sort.Slice(mySlice, func(i, j int) bool {
return mySlice[i].age < mySlice[j].age
})
fmt.Println(mySlice)