当前位置:  首页>> 技术小册>> 数据结构与算法(中)

难度:
Hard

题意:

  1. 一个特殊的类栈数据结构,具有两种操作
  2. push x:表示将x入栈
  3. pop:表示将栈中最多的数弹出,相同数量的数弹出最近入栈的一个数

思路:

  • 这个题的数据结构中,x是key,既需要根据x来操作,又需要根据x的数量和入栈时间来出栈,典型的双向查找表

  • 维护一个x到x的入栈时间的映射关系,入栈时间我们定义为第几次push操作,即x->[t1,t2,t3]

  • 维护一个有序的x的入栈时间到x的对应表,比较函数定义为:栈中元素个数,和栈顶时间

代码:

  1. class FreqStack {
  2. int _count;
  3. private class Item implements Comparable<Item> {
  4. LinkedList<Integer> time;
  5. public Item(LinkedList<Integer> time) {
  6. this.time = time;
  7. }
  8. public LinkedList<Integer> getTime() {
  9. return time;
  10. }
  11. @Override
  12. public int compareTo(Item o) {
  13. if (time.size() == o.time.size()) {
  14. return Integer.compare(o.time.getLast(), time.getLast());
  15. } else {
  16. return Integer.compare(o.time.size(), time.size());
  17. }
  18. }
  19. }
  20. TreeMap<Item, Integer> freqToId;
  21. Map<Integer, Item> idToFreq;
  22. public FreqStack() {
  23. _count = 0;
  24. freqToId = new TreeMap<Item, Integer>();
  25. idToFreq = new HashMap<Integer, Item>();
  26. }
  27. public void push(int x) {
  28. if (!idToFreq.containsKey(x)) {
  29. LinkedList<Integer> time = new LinkedList<Integer>();
  30. time.addLast(_count++);
  31. Item item = new Item(time);
  32. freqToId.put(item, x);
  33. idToFreq.put(x, item);
  34. } else {
  35. Item origin = idToFreq.get(x);
  36. freqToId.remove(origin);
  37. LinkedList<Integer> time = origin.time;
  38. time.addLast(_count++);
  39. Item item = new Item(time);
  40. idToFreq.put(x, item);
  41. freqToId.put(item, x);
  42. }
  43. }
  44. public int pop() {
  45. Map.Entry<Item, Integer> first = freqToId.firstEntry();
  46. freqToId.remove(first.getKey());
  47. idToFreq.remove(first.getValue());
  48. LinkedList<Integer> time = first.getKey().time;
  49. time.removeLast();
  50. if (time.size() != 0) {
  51. Item item = new Item(time);
  52. idToFreq.put(first.getValue(), item);
  53. freqToId.put(item, first.getValue());
  54. }
  55. return first.getValue();
  56. }
  57. }

该分类下的相关小册推荐: