leetcode 911. Online Election | 911. 在线选举(加强堆 + 二分查找)

x33g5p2x  于2021-12-12 转载在 其他  
字(2.3k)|赞(0)|评价(0)|浏览(393)

题目

https://leetcode.com/problems/online-election/

题解

我的解法是,用预计算(加强堆,O(nlogn)) + 二分查找(用的自带TreeMap,查找复杂度O(logn))。

实际上,最优解可以达到预计算 O(n),只需要比较当前新元素的 count 与当前最大元素的 count,并更新最大元素即可。

下面来说一下为什么用加强堆。

系统自带的堆,它不能动态修改元素。
就是说,已经入堆的元素,如果参与排序的指标方法变化,它不能自动调整。所以有了加强堆。
对于已经入堆的元素,它的字段发生改变的时候,能够以O(logN)的复杂度调整整个堆。

  1. class TopVotedCandidate {
  2. TreeSet<Info> treeSet;
  3. public TopVotedCandidate(int[] persons, int[] times) {
  4. HeapGreater<Person> heap = new HeapGreater<>((o1, o2) -> {
  5. if (o1.count != o2.count) {
  6. return o2.count - o1.count;
  7. } else {
  8. return o2.updatedTime - o1.updatedTime;
  9. }
  10. });
  11. HashMap<Integer, Person> map = new HashMap<>(); // index, person
  12. treeSet = new TreeSet<>((o1, o2) -> o1.time - o2.time);
  13. for (int i = 0; i < persons.length; i++) {
  14. if (!map.containsKey(persons[i])) {
  15. Person p = new Person(1, persons[i], times[i]);
  16. map.put(persons[i], p);
  17. heap.push(p);
  18. } else {
  19. Person p = map.get(persons[i]);
  20. p.count++;
  21. p.updatedTime = times[i];
  22. heap.resign(p);
  23. }
  24. treeSet.add(new Info(heap.peek().index, times[i]));
  25. }
  26. }
  27. public int q(int t) {
  28. return treeSet.floor(new Info(-1, t)).index;
  29. }
  30. }
  31. class Info {
  32. int index;
  33. int time;
  34. public Info(int index, int time) {
  35. this.index = index;
  36. this.time = time;
  37. }
  38. }
  39. class Person {
  40. int count;
  41. int index;
  42. int updatedTime;
  43. public Person(int count, int index, int updatedTime) {
  44. this.count = count;
  45. this.index = index;
  46. this.updatedTime = updatedTime;
  47. }
  48. }
  49. /* * T一定要是非基础类型,有基础类型需求包一层 */
  50. class HeapGreater<T> {
  51. private ArrayList<T> heap;
  52. private HashMap<T, Integer> indexMap;
  53. private int heapSize;
  54. private Comparator<? super T> comp;
  55. public HeapGreater(Comparator<T> c) {
  56. heap = new ArrayList<>();
  57. indexMap = new HashMap<>();
  58. heapSize = 0;
  59. comp = c;
  60. }
  61. public T peek() {
  62. return heap.get(0);
  63. }
  64. public void push(T obj) {
  65. heap.add(obj);
  66. indexMap.put(obj, heapSize);
  67. heapInsert(heapSize++);
  68. }
  69. public void resign(T obj) {
  70. heapInsert(indexMap.get(obj));
  71. heapify(indexMap.get(obj));
  72. }
  73. private void heapInsert(int index) {
  74. while (comp.compare(heap.get(index), heap.get((index - 1) / 2)) < 0) {
  75. swap(index, (index - 1) / 2);
  76. index = (index - 1) / 2;
  77. }
  78. }
  79. private void heapify(int index) {
  80. int left = index * 2 + 1;
  81. while (left < heapSize) {
  82. int best = left + 1 < heapSize && comp.compare(heap.get(left + 1), heap.get(left)) < 0 ? (left + 1) : left;
  83. best = comp.compare(heap.get(best), heap.get(index)) < 0 ? best : index;
  84. if (best == index) {
  85. break;
  86. }
  87. swap(best, index);
  88. index = best;
  89. left = index * 2 + 1;
  90. }
  91. }
  92. private void swap(int i, int j) {
  93. T o1 = heap.get(i);
  94. T o2 = heap.get(j);
  95. heap.set(i, o2);
  96. heap.set(j, o1);
  97. indexMap.put(o2, i);
  98. indexMap.put(o1, j);
  99. }
  100. }

相关文章