Skip to content

347. Top K Frequent Elements#9

Open
n6o wants to merge 1 commit intomainfrom
top-k-frequent-elements
Open

347. Top K Frequent Elements#9
n6o wants to merge 1 commit intomainfrom
top-k-frequent-elements

Conversation

@n6o
Copy link
Owner

@n6o n6o commented Feb 6, 2026

今回の問題

Top K Frequent Elements - LeetCode

使用言語

Go

次に解く問題

Find K Pairs with Smallest Sums - LeetCode

- ヒープ版を書く

```go
import "container/heap"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swap、Less、Len、Push、Pop を与えると動くというのがこのライブラリーの仕様なんですね。
https://pkg.go.dev/container/heap
時々公式ドキュメントを見ておきましょう。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。
ライブラリURLの提示が漏れており失礼しました。

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「インターフェースを満たしていれば何でも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.
}

https://pkg.go.dev/sort#Interface

Comment on lines +42 to +52
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
})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

countscounters という、名前が似た変数が出てくるのが読んでいて紛らわしかったです。また、情報としてもちょっと冗長な印象を受けました。ただしこれは、私がPythonなどのより短く書ける言語に慣れているからかもしれません。

自分なら、ユニークな数字のスライスを作って、counts を引くようにします。

Suggested change
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はメインルーチンで使わないので)。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。

キーのソートのときに 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
}

@mamo3gr
Copy link

mamo3gr commented Feb 7, 2026

大変勉強になりました。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants