Advertisement
jorupp

https://leetcode.com/problems/minimum-time-to-repair-cars

Aug 18th, 2023
15
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.09 KB | None | 0 0
  1. function repairCars(ranks: number[], cars: number): number {
  2. if (cars === 0) return 0;
  3. // https://stackoverflow.com/a/42919752
  4. const top: number = 0;
  5. const parent = (i: number) => ((i + 1) >>> 1) - 1;
  6. const left = (i: number) => (i << 1) + 1;
  7. const right = (i: number) => (i + 1) << 1;
  8.  
  9. class PriorityQueue {
  10. private _heap: number[];
  11. private _comparator: (a: number, b: number) => boolean;
  12. constructor(comparator = (a: number, b: number) => a > b) {
  13. this._heap = [];
  14. this._comparator = comparator;
  15. }
  16. size() {
  17. return this._heap.length;
  18. }
  19. isEmpty() {
  20. return this.size() == 0;
  21. }
  22. peek() {
  23. return this._heap[top];
  24. }
  25. push(...values) {
  26. values.forEach(value => {
  27. this._heap.push(value);
  28. this._siftUp();
  29. });
  30. return this.size();
  31. }
  32. pop() {
  33. const poppedValue = this.peek();
  34. const bottom = this.size() - 1;
  35. if (bottom > top) {
  36. this._swap(top, bottom);
  37. }
  38. this._heap.pop();
  39. this._siftDown();
  40. return poppedValue;
  41. }
  42. replace(value) {
  43. const replacedValue = this.peek();
  44. this._heap[top] = value;
  45. this._siftDown();
  46. return replacedValue;
  47. }
  48. _greater(i, j) {
  49. return this._comparator(this._heap[i], this._heap[j]);
  50. }
  51. _swap(i, j) {
  52. [this._heap[i], this._heap[j]] = [this._heap[j], this._heap[i]];
  53. }
  54. _siftUp() {
  55. let node = this.size() - 1;
  56. while (node > top && this._greater(node, parent(node))) {
  57. this._swap(node, parent(node));
  58. node = parent(node);
  59. }
  60. }
  61. _siftDown() {
  62. let node = top;
  63. while (
  64. (left(node) < this.size() && this._greater(left(node), node)) ||
  65. (right(node) < this.size() && this._greater(right(node), node))
  66. ) {
  67. let maxChild = (right(node) < this.size() && this._greater(right(node), left(node))) ? right(node) : left(node);
  68. this._swap(node, maxChild);
  69. node = maxChild;
  70. }
  71. }
  72. }
  73.  
  74. // collapse duplicate ranks together
  75. const counts = new Map<number, number>();
  76. for(const r of ranks) {
  77. if (!counts.has(r)) {
  78. counts.set(r, 0);
  79. }
  80. counts.set(r, counts.get(r) + 1);
  81. }
  82.  
  83. const distinctRanks = Array.from(counts.keys()).map(i => i);
  84. const count = distinctRanks.map(i => 0);
  85. const nextCost = distinctRanks.map(i => i);
  86. const queue = new PriorityQueue((a,b) => nextCost[a] < nextCost[b]);
  87. for(let i=0; i<nextCost.length; i++) {
  88. queue.push(i);
  89. }
  90.  
  91. let lastCost = 0;
  92. while(cars > 0) {
  93. const ix = queue.pop();
  94. lastCost = nextCost[ix];
  95. count[ix]++;
  96. nextCost[ix] = distinctRanks[ix] * (count[ix]+1) * (count[ix]+1);
  97.  
  98. let ixCount = counts.get(distinctRanks[ix]);
  99. //console.log(`${ix}: ${ixCount} * ${distinctRanks[ix]} given car ${count[ix]} at total cost ${lastCost}`);
  100. while(cars > 0 && ixCount > 0) {
  101. cars--;
  102. ixCount--;
  103. }
  104.  
  105. queue.push(ix);
  106. }
  107. return lastCost;
  108. };
  109.  
  110.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement