leetcode49字母异位词分组

leetcode49 Group Anagrams

Posted by BY on February 18, 2019

前言

新的一年,好好学习

正文

问题来源

本问题来自leetcode上的49题。

问题描述

给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。

示例 1:

输入: ["eat", "tea", "tan", "ate", "nat", "bat"],
输出:
[
  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]

分析:

主体思想:暴力 时间复杂度:O(N^3) 字符串比较时间复杂度也需要算入 详细过程:首先判断是否字典内存在相同已排序的字符串,如果存在就在最终结果相同索引位置加入元素;如果不存在就将已排序的字符串加入字典,同时开辟空间将字符串加入,并将开辟好的空间加入最终结果内。

//go语言没有将字符串内元素排序的函数
type sortRunes []rune
func (s sortRunes) Less(i, j int) bool {
    return s[i] < s[j]
}

func (s sortRunes) Swap(i, j int) {
    s[i], s[j] = s[j], s[i]
}

func (s sortRunes) Len() int {
    return len(s)
}
//调用接口
func SortString(s string) string {
    r := []rune(s)
    //调用go自带函数
    sort.Sort(sortRunes(r))
    return string(r)
}

func groupAnagrams(strs []string) [][]string {
    ret := make([][]string, 0)
    m := make([]string, 0)
    for i := 0; i < len(strs); i++ {
        
        temp := SortString(strs[i]) //排序字符串
        flag := false
        for j := 0; j < len(m); j++ {
            if temp == m[j] {
                flag = true//已找到
                ret[j] = append(ret[j], strs[i])//在最终结果相同索引处加入该字符串
            }
        }
        if false == flag { //并未找到排序的相同字符串
            m = append(m, temp) //加入字典
            retTemp := append([]string{}, strs[i]) //开辟空间并加入
            ret = append(ret, retTemp)//加入最终结果
        }
    }
    
    return ret
}

提交结果:
执行用时: 956 ms, 在Group Anagrams的Go提交中击败了7.75% 的用户
内存消耗: 122.9 MB, 在Group Anagrams的Go提交中击败了36.36% 的用户
并不是很满意这样的一个提交结果。

可以将排序的字符串放入map而不是slice。若是输入的字符串过长(远超26个字符),可以将SortString改为如下函数。排序的时间复杂度为n * logn。

func countSort(s string) string {
    var cnt [26]int
    for i := 0; i < len(s); i++ {
        cnt[s[i]-byte('a')]++
    }
    ret := make([]byte, len(s))
    j := 0
    for i := 0; i < 26; i++ {
        for k := 0; k < cnt[i]; k++ {
            ret[j] = byte(i) + byte('a')
            j++
        }
    }
    return string(ret)
}
func groupAnagrams(strs []string) [][]string {
    mp := map[string][]string{}
    for _, str := range strs {
        s := []byte(str)
        sort.Slice(s, func(i, j int) bool { return s[i] < s[j] })
        sortedStr := string(s)
        mp[sortedStr] = append(mp[sortedStr], str)
    }
    ans := make([][]string, 0, len(mp))
    for _, v := range mp {
        ans = append(ans, v)
    }
    return ans
}

总结:

勤思考。

结语

不管怎么样好好加油。