|
3 | 3 | * @return {number[][]}
|
4 | 4 | */
|
5 | 5 | const findMatrix = function(nums) {
|
6 |
| - const p1 = new PQ((a, b) => a.cnt > b.cnt) |
7 |
| - const p2 = new PQ((a, b) => a.cnt > b.cnt) |
8 |
| - |
| 6 | + |
9 | 7 | const hash = new Map()
|
10 | 8 | for(const e of nums) {
|
11 | 9 | if(!hash.has(e)) hash.set(e, 0)
|
12 | 10 | hash.set(e, hash.get(e) + 1)
|
13 | 11 | }
|
14 | 12 |
|
| 13 | + const arr = [] |
15 | 14 | for(const [k, v] of hash) {
|
16 |
| - p1.push({val: k, cnt: v}) |
| 15 | + arr.push([v, k]) |
17 | 16 | }
|
18 | 17 |
|
| 18 | + arr.sort((a, b) => b[0] - a[0]) |
19 | 19 |
|
20 | 20 | const res = []
|
21 |
| - while(p1.size() || p2.size()) { |
22 |
| - const tmp = [] |
23 |
| - |
24 |
| - if(p1.size()) { |
25 |
| - while(p1.size()) { |
26 |
| - const e = p1.pop() |
27 |
| - let {val, cnt} = e |
28 |
| - tmp.push(val) |
29 |
| - if(--cnt > 0) p2.push({val, cnt}) |
30 |
| - } |
31 |
| - |
32 |
| - } else { |
33 |
| - while(p2.size()) { |
34 |
| - const e = p2.pop() |
35 |
| - let {val, cnt} = e |
36 |
| - tmp.push(val) |
37 |
| - if(--cnt > 0) p1.push({val, cnt}) |
38 |
| - } |
39 |
| - |
| 21 | + for(let i = 0, len = arr.length; i < len; i++) { |
| 22 | + const [freq, val] = arr[i] |
| 23 | + for(let j = 0; j < freq; j++) { |
| 24 | + if(res[j] == null) res[j] = [] |
| 25 | + res[j].push(val) |
40 | 26 | }
|
41 |
| - |
42 |
| - res.push(tmp) |
43 | 27 | }
|
44 | 28 |
|
45 | 29 | return res
|
46 | 30 | };
|
47 |
| - |
48 |
| -class PQ { |
49 |
| - constructor(comparator = (a, b) => a > b) { |
50 |
| - this.heap = [] |
51 |
| - this.top = 0 |
52 |
| - this.comparator = comparator |
53 |
| - } |
54 |
| - size() { |
55 |
| - return this.heap.length |
56 |
| - } |
57 |
| - isEmpty() { |
58 |
| - return this.size() === 0 |
59 |
| - } |
60 |
| - peek() { |
61 |
| - return this.heap[this.top] |
62 |
| - } |
63 |
| - push(...values) { |
64 |
| - values.forEach((value) => { |
65 |
| - this.heap.push(value) |
66 |
| - this.siftUp() |
67 |
| - }) |
68 |
| - return this.size() |
69 |
| - } |
70 |
| - pop() { |
71 |
| - const poppedValue = this.peek() |
72 |
| - const bottom = this.size() - 1 |
73 |
| - if (bottom > this.top) { |
74 |
| - this.swap(this.top, bottom) |
75 |
| - } |
76 |
| - this.heap.pop() |
77 |
| - this.siftDown() |
78 |
| - return poppedValue |
79 |
| - } |
80 |
| - replace(value) { |
81 |
| - const replacedValue = this.peek() |
82 |
| - this.heap[this.top] = value |
83 |
| - this.siftDown() |
84 |
| - return replacedValue |
85 |
| - } |
86 |
| - |
87 |
| - parent = (i) => ((i + 1) >>> 1) - 1 |
88 |
| - left = (i) => (i << 1) + 1 |
89 |
| - right = (i) => (i + 1) << 1 |
90 |
| - greater = (i, j) => this.comparator(this.heap[i], this.heap[j]) |
91 |
| - swap = (i, j) => ([this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]]) |
92 |
| - siftUp = () => { |
93 |
| - let node = this.size() - 1 |
94 |
| - while (node > this.top && this.greater(node, this.parent(node))) { |
95 |
| - this.swap(node, this.parent(node)) |
96 |
| - node = this.parent(node) |
97 |
| - } |
98 |
| - } |
99 |
| - siftDown = () => { |
100 |
| - let node = this.top |
101 |
| - while ( |
102 |
| - (this.left(node) < this.size() && this.greater(this.left(node), node)) || |
103 |
| - (this.right(node) < this.size() && this.greater(this.right(node), node)) |
104 |
| - ) { |
105 |
| - let maxChild = |
106 |
| - this.right(node) < this.size() && |
107 |
| - this.greater(this.right(node), this.left(node)) |
108 |
| - ? this.right(node) |
109 |
| - : this.left(node) |
110 |
| - this.swap(node, maxChild) |
111 |
| - node = maxChild |
112 |
| - } |
113 |
| - } |
114 |
| -} |
0 commit comments