-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathTopKFrequent.kt
63 lines (54 loc) · 1.91 KB
/
TopKFrequent.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package questions
import _utils.UseCommentAsDocumentation
import utils.shouldBeOneOf
import java.util.*
/**
* Given an integer array nums and an integer k, return the k most frequent elements.
* You may return the answer in any order.
* [Source](https://leetcode.com/problems/top-k-frequent-elements//)
*/
@UseCommentAsDocumentation
fun topKFrequent(nums: IntArray, k: Int): IntArray {
val charToCountMap = HashMap<Int, Int>(nums.size / 2)
// Reverse sorted map of frequency to [nums] element
val frequencyToCharMap = TreeMap<Int, MutableSet<Int>>(object : Comparator<Int> {
override fun compare(o1: Int?, o2: Int?): Int {
return o2!! - o1!! // This will be sorted in reverse order of frequency
}
})
for (i in 0..nums.lastIndex) {
val value = nums[i]
val prevCount = charToCountMap.getOrDefault(value, 0)
val newCount = prevCount + 1
charToCountMap[value] = newCount
if (prevCount > 0) {
// it has been encountered before
// so remove it from its old key
val set = frequencyToCharMap.getOrDefault(prevCount, mutableSetOf())
set.remove(value)
}
// and add it to [newCount] key
val set = frequencyToCharMap.getOrDefault(newCount, mutableSetOf())
set.add(value)
frequencyToCharMap[newCount] = set
}
// Since [frequencyToCharMap] is reverse sorted, top k elements should be in first few position
val result = IntArray(k) { 0 }
var index = 0
for (numSet in frequencyToCharMap.values) {
for (value in numSet) {
result[index] = value
if (index >= k) {
break
}
index++
}
if (index >= k) {
break
}
}
return result
}
fun main() {
topKFrequent(intArrayOf(1, 1, 1, 2, 2, 3), 2) shouldBeOneOf listOf(intArrayOf(1, 2), intArrayOf(2, 1))
}