请你设计一个用于存储字符串计数的数据结构,并能够返回计数最小和最大的字符串。

    实现 AllOne 类:

    AllOne() 初始化数据结构的对象。
    inc(String key) 字符串 key 的计数增加 1 。如果数据结构中尚不存在 key ,那么插入计数为 1 的 key 。
    dec(String key) 字符串 key 的计数减少 1 。如果 key 的计数在减少后为 0 ,那么需要将这个 key 从数据结构中删除。测试用例保证:在减少计数前,key 存在于数据结构中。
    getMaxKey() 返回任意一个计数最大的字符串。如果没有元素存在,返回一个空字符串 “” 。
    getMinKey() 返回任意一个计数最小的字符串。如果没有元素存在,返回一个空字符串 “” 。

    示例:

    输入
    [“AllOne”, “inc”, “inc”, “getMaxKey”, “getMinKey”, “inc”, “getMaxKey”, “getMinKey”]
    [[], [“hello”], [“hello”], [], [], [“leet”], [], []]
    输出
    [null, null, null, “hello”, “hello”, null, “hello”, “leet”]

    解释
    AllOne allOne = new AllOne();
    allOne.inc(“hello”);
    allOne.inc(“hello”);
    allOne.getMaxKey(); // 返回 “hello”
    allOne.getMinKey(); // 返回 “hello”
    allOne.inc(“leet”);
    allOne.getMaxKey(); // 返回 “hello”
    allOne.getMinKey(); // 返回 “leet”

    提示:

    1 <= key.length <= 10
    key 由小写英文字母组成
    测试用例保证:在每次调用 dec 时,数据结构中总存在 key
    最多调用 inc、dec、getMaxKey 和 getMinKey 方法 5 * 104 次


    1. class AllOne {
    2. /**
    3. 定义node节点,双向链表,里面有cnt属性值记录次数,还有set集合保存key值, 用map存key与node的映射,当我们删除增加的时候,先寻找node左右是否有目标值,有的话就把key值存到目标节点的set中,没有则创建
    4. */
    5. class Node {
    6. int cnt;
    7. Node left, right;
    8. Set<String> set = new HashSet<>();
    9. public Node(int cnt) {
    10. this.cnt = cnt;
    11. }
    12. }
    13. //如果key数量为0,就要删除掉这个节点
    14. public void clear(Node node) {
    15. if (node.set.size() == 0) {
    16. node.left.right = node.right;
    17. node.right.left = node.left;
    18. }
    19. }
    20. Node hh = new Node(-1), tt = new Node(-1);
    21. Map<String, Node> map = new HashMap<>();
    22. public AllOne() {
    23. hh.right = tt;
    24. tt.left = hh;
    25. }
    26. public void inc(String key) {
    27. //map中有该节点
    28. if (map.containsKey(key)) {
    29. Node node = map.get(key);
    30. //先删除set中的key值
    31. node.set.remove(key);
    32. Node next = null;
    33. //分情况,有目标节点和无目标节点
    34. if (node.right.cnt == node.cnt + 1) {
    35. next = node.right;
    36. } else {
    37. next = new Node(node.cnt + 1);
    38. //更改指针
    39. node.right.left = next;
    40. next.right = node.right;
    41. node.right = next;
    42. next.left = node;
    43. }
    44. next.set.add(key);
    45. //更新map
    46. map.put(key, next);
    47. clear(node);
    48. } else { //没有该节点
    49. Node node = null;
    50. if (hh.right.cnt == 1) {
    51. node = hh.right;
    52. } else {
    53. node = new Node(1);
    54. //更改指针
    55. node.left = hh;
    56. node.right = hh.right;
    57. hh.right.left = node;
    58. hh.right = node;
    59. }
    60. node.set.add(key);
    61. map.put(key, node);
    62. //不存在clear
    63. }
    64. }
    65. public void dec(String key) {
    66. //删除必定map中存在
    67. Node node = map.get(key);
    68. node.set.remove(key);
    69. Node pre = null;
    70. //说明只出现一次,那么删除后就没有key值,所以直接map删即可
    71. if (node.cnt == 1) {
    72. map.remove(key);
    73. } else {
    74. if (node.left.cnt == node.cnt - 1) {
    75. pre = node.left;
    76. } else {
    77. pre = new Node(node.cnt - 1);
    78. node.left.right = pre;
    79. pre.left = node.left;
    80. node.left = pre;
    81. pre.right = node;
    82. }
    83. pre.set.add(key);
    84. map.put(key, pre);
    85. }
    86. clear(node);
    87. }
    88. public String getMaxKey() {
    89. Node node = tt.left;
    90. //返回任意一个
    91. for (String s : node.set) return s;
    92. return "";
    93. }
    94. public String getMinKey() {
    95. Node node = hh.right;
    96. for (String s : node.set) return s;
    97. return "";
    98. }
    99. }
    100. /**
    101. * Your AllOne object will be instantiated and called as such:
    102. * AllOne obj = new AllOne();
    103. * obj.inc(key);
    104. * obj.dec(key);
    105. * String param_3 = obj.getMaxKey();
    106. * String param_4 = obj.getMinKey();
    107. */