package top_k_frequent_elements /// O(n*log(n)) // func ToMultiset(nums []int) map[int]int { // result := map[int]int{} // for _, num := range nums { // result[num]++ // } // return result // } // func ToEntries(multiset map[int]int) [][2]int { // result := [][2]int{} // for num, amount := range multiset { // result = append(result, [2]int{num, amount}) // } // return result // } // func ByDescendingAmount(a, b [2]int) int { // return b[1] - a[1] // } // func GetNumbers(entries [][2]int) []int { // amounts := []int{} // for _, entry := range entries { // amounts = append(amounts, entry[0]) // } // return amounts // } // func TopKFrequent(nums []int, k int) []int { // multiset := ToMultiset(nums) // entries := ToEntries(multiset) // slices.SortFunc(entries, ByDescendingAmount) // return GetNumbers(entries[0:k]) // } /// O(n) func ToMultiset(nums []int) map[int]int { result := map[int]int{} for _, num := range nums { result[num]++ } return result } func TopKFrequent(nums []int, k int) []int { multiset := ToMultiset(nums) // Bucket Sort. // // A multiset's frequency is always less then or equal to the length of the // original list. So, you can use bucket sort to sort the items in O(n). frequencies := make([][]int, len(nums)) for value, amount := range multiset { if frequencies[amount-1] == nil { frequencies[amount-1] = []int{} } frequencies[amount-1] = append(frequencies[amount-1], value) } top_frequencies := []int{} for i := len(nums) - 1; i >= 0; i-- { for _, num := range frequencies[i] { top_frequencies = append(top_frequencies, num) if len(top_frequencies) == k { return top_frequencies } } } return top_frequencies }