0049.Grop Anagrams

題目

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 lowercase English letters.

題目大意

分組出只用同樣字符產生的的單字

解題思路

方法一: 計數 由於互為字母異位詞的兩個字串包含的字母相同,因此兩個字串中的相同字母出現的次數一定是相同的,故可以將每個字母出現的次數使用字串表示,作為哈希表的鍵。

方法二: 排序 由於互為字母異位詞的兩個字串包含的字母相同,因此對兩個字串分別進行排序之後得到的字串一定是相同的,故可以將排序之後的字串作為哈希表的鍵。

來源

解答

https://github.com/kimi0230/LeetcodeGolang/blob/master/Leetcode/0049.Group-Anagams/main.go

package groupanagrams

import "sort"

// 使用計數: 時間複雜 O(nk), 空間複雜 O(nk)
// n 是單詞的個數 , k是單字的最大長度
// O(n)遍歷單詞, 遍歷字符O(nk)
func GroupAnagrams(strs []string) [][]string {
    m := make(map[[26]int][]string, len(strs))

    for _, str := range strs {
        // 建立每一個string的特徵`count`, 藉由統計每個字母出現的次數
        count := [26]int{}
        for _, b := range str {
            count[b-'a']++
        }
        // 將同樣的次數的string放置在 map中
        m[count] = append(m[count], str)
    }

    // 把map中的string放入到結果的 `[][]string` array 中
    ans := [][]string{}
    for _, v := range m {
        ans = append(ans, v)
    }
    return ans
}

// 排序: 時間複雜 O(nklog(k)), 空間複雜 O(klog(k))
// n 是單詞的個數 , k是單字的最大長度
// 遍歷單詞 O(n)
// 排序字符 O(klog(k))
func GroupAnagramsBySort(strs []string) [][]string {
    m := make(map[string][]string, len(strs))

    for _, str := range strs {
        // 建立每一個string的特徵, 藉由統計排序
        s := []byte(str)
        sort.Slice(s, func(i, j int) bool { return s[i] < s[j] })
        sortedStr := string(s)

        // 將同樣的特徵的string放置在 map中
        m[sortedStr] = append(m[sortedStr], str)
    }

    // 把map中的string放入到結果的 `[][]string` array 中
    ans := [][]string{}
    for _, v := range m {
        ans = append(ans, v)
    }
    return ans
}

Benchmark

go test -benchmem -run=none LeetcodeGolang/Leetcode/0049.Group-Anagrams -bench=.
goos: darwin
goarch: amd64
pkg: LeetcodeGolang/Leetcode/0049.Group-Anagrams
cpu: Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
BenchmarkGroupAnagrams-8                  899431              1615 ns/op             968 B/op         12 allocs/op
BenchmarkGroupAnagramsBySort-8            592148              3566 ns/op             776 B/op         33 allocs/op
PASS
ok      LeetcodeGolang/Leetcode/0049.Group-Anagrams     3.611s
package groupanagrams

import (
    "reflect"
    "sort"
    "testing"
)

var tests = []struct {
    arg1 []string
    want [][]string
}{
    {
        []string{"eat", "tea", "tan", "ate", "nat", "bat"},
        [][]string{
            {"bat"}, {"nat", "tan"}, {"ate", "eat", "tea"}},
    },
    {
        []string{},
        [][]string{},
    }, {
        []string{"a"},
        [][]string{
            {"a"}},
    },
}

// 創建一個輔助函數,將字符串數組排序,以便比較
func sortSubStrings(groups [][]string) {
    for _, group := range groups {
        sort.Strings(group)
    }
    // 排序整個切片
    sort.Slice(groups, func(i, j int) bool {
        return groups[i][0] < groups[j][0]
    })
}

func TestGroupAnagrams(t *testing.T) {
    for _, tt := range tests {
        result := GroupAnagrams(tt.arg1)
        // 對結果進行排序,以便比較
        sortSubStrings(result)

        // 對期望結果進行排序,以便比較
        sortSubStrings(tt.want)

        // 使用反射檢查結果和期望是否相同
        if !reflect.DeepEqual(result, tt.want) {
            t.Errorf("got = %v, want = %v", result, tt.want)
        }
    }
}

func TestGroupAnagramsBySort(t *testing.T) {
    for _, tt := range tests {
        result := GroupAnagramsBySort(tt.arg1)
        // 對結果進行排序,以便比較
        sortSubStrings(result)

        // 對期望結果進行排序,以便比較
        sortSubStrings(tt.want)

        // 使用反射檢查結果和期望是否相同
        if !reflect.DeepEqual(result, tt.want) {
            t.Errorf("got = %v, want = %v", result, tt.want)
        }
    }
}

func BenchmarkGroupAnagrams(b *testing.B) {
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        GroupAnagrams(tests[0].arg1)
    }
}

func BenchmarkGroupAnagramsBySort(b *testing.B) {
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        GroupAnagramsBySort(tests[0].arg1)
    }
}
© Kimi Tsai all right reserved.            Updated : 2024-05-06 09:36:37

results matching ""

    No results matching ""