Conversation
| - ヒープ版を書く | ||
|
|
||
| ```go | ||
| import "container/heap" |
There was a problem hiding this comment.
Swap、Less、Len、Push、Pop を与えると動くというのがこのライブラリーの仕様なんですね。
https://pkg.go.dev/container/heap
時々公式ドキュメントを見ておきましょう。
There was a problem hiding this comment.
ありがとうございます。
ライブラリURLの提示が漏れており失礼しました。
There was a problem hiding this comment.
「インターフェースを満たしていれば何でもheapである」とみなすのがGoっぽくていいですね。sortのインターフェースが埋め込んであるのも良い設計に思えます。
https://pkg.go.dev/container/heap#Interface
type Interface interface {
[sort](https://pkg.go.dev/sort).[Interface](https://pkg.go.dev/sort#Interface)
Push(x [any](https://pkg.go.dev/builtin#any)) // add x as element Len()
Pop() [any](https://pkg.go.dev/builtin#any) // remove and return element Len() - 1.
}| counters := make([]counter, 0, len(counts)) | ||
| for n, c := range counts { | ||
| counters = append(counters, counter{ | ||
| num: n, | ||
| count: c, | ||
| }) | ||
| } | ||
|
|
||
| slices.SortFunc(counters, func(a, b counters) int { | ||
| return a.count - b.count | ||
| }) |
There was a problem hiding this comment.
counts と counters という、名前が似た変数が出てくるのが読んでいて紛らわしかったです。また、情報としてもちょっと冗長な印象を受けました。ただしこれは、私がPythonなどのより短く書ける言語に慣れているからかもしれません。
自分なら、ユニークな数字のスライスを作って、counts を引くようにします。
| counters := make([]counter, 0, len(counts)) | |
| for n, c := range counts { | |
| counters = append(counters, counter{ | |
| num: n, | |
| count: c, | |
| }) | |
| } | |
| slices.SortFunc(counters, func(a, b counters) int { | |
| return a.count - b.count | |
| }) | |
| keys := make([]int, 0, len(counts)) | |
| for n := range counts { | |
| keys = append(keys, n) | |
| } | |
| slices.SortFunc(keys, func(a, b int) int { | |
| return counts[b] - counts[a] | |
| }) |
あるいは、nums を受け取って counters のスライスを返すサブルーチンを切り出します(この場合、countsはメインルーチンで使わないので)。
There was a problem hiding this comment.
ありがとうございます。
キーのソートのときに counts を参照して、登場回数の降順で並べるのですね。
勉強になりました。
関数を切り出す版
関数を切り出すならこんな感じかなと実装してみました。
func topKFrequent(nums []int, k int) []int {
counters := newCounters(nums)
slices.SortFunc(counters, func(a, b counter) int {
return a.count - b.count
})
counters = counters[len(counters) - k:]
result := make([]int, k)
for i := range counters {
result[i] = counters[i].num
}
return result
}
func newCounters(nums []int) []counter {
counts := map[int]int{}
for _, n := range nums {
counts[n]++
}
counters := make([]counter, 0, len(counts))
for n, c := range counts {
counters = append(counters, counter{
num: n,
count: c,
})
}
return counters
}
type counter struct {
num int
count int
}|
大変勉強になりました。 |
今回の問題
Top K Frequent Elements - LeetCode
使用言語
Go
次に解く問題
Find K Pairs with Smallest Sums - LeetCode