之前在做LRU这道题时,用到了双端链表,今天在完成Leetcode的每日一题时,发现利用双端链表可以完成解答。

    First Unique Number You have a queue of integers, you need to retrieve the first unique integer in the queue. Implement the FirstUnique class:

    • FirstUnique(int[] nums) Initializes the object with the numbers in the queue.
    • int showFirstUnique() returns the value of the first unique integer of the queue, and returns -1 if there is no such integer.
    • void add(int value) insert value to the queue.

    Example 1: Input:

    [“FirstUnique”,”showFirstUnique”,”add”,”showFirstUnique”,”add”,”showFirstUnique”,”add”,”showFirstUnique”]

    [[[2,3,5]],[],[5],[],[2],[],[3],[]]

    Output:

    [null,2,null,2,null,3,null,-1]

    Explanation:

    FirstUnique firstUnique = new FirstUnique([2,3,5]);

    firstUnique.showFirstUnique(); // return 2

    firstUnique.add(5); // the queue is now [2,3,5,5]

    firstUnique.showFirstUnique(); // return 2

    firstUnique.add(2); // the queue is now [2,3,5,5,2]

    firstUnique.showFirstUnique(); // return 3

    firstUnique.add(3); // the queue is now [2,3,5,5,2,3]

    firstUnique.showFirstUnique(); // return -1

    Example 2:

    Input:

    [“FirstUnique”,”showFirstUnique”,”add”,”add”,”add”,”add”,”add”,”showFirstUnique”]

    [[[7,7,7,7,7,7]],[],[7],[3],[3],[7],[17],[]]

    Output:

    [null,-1,null,null,null,null,null,17]

    Explanation:

    FirstUnique firstUnique = new FirstUnique([7,7,7,7,7,7]);

    firstUnique.showFirstUnique(); // return -1

    firstUnique.add(7); // the queue is now [7,7,7,7,7,7,7]

    firstUnique.add(3); // the queue is now [7,7,7,7,7,7,7,3]

    firstUnique.add(3); // the queue is now [7,7,7,7,7,7,7,3,3]

    firstUnique.add(7); // the queue is now [7,7,7,7,7,7,7,3,3,7]

    firstUnique.add(17); // the queue is now [7,7,7,7,7,7,7,3,3,7,17]

    firstUnique.showFirstUnique(); // return 17

    Example 3:

    Input:

    [“FirstUnique”,”showFirstUnique”,”add”,”showFirstUnique”]

    [[[809]],[],[809],[]]

    Output:

    [null,809,null,-1]

    Explanation:

    FirstUnique firstUnique = new FirstUnique([809]);

    firstUnique.showFirstUnique(); // return 809

    firstUnique.add(809); // the queue is now [809,809]

    firstUnique.showFirstUnique(); // return -1

    Constraints:

    • 1 <= nums.length <= 10^5
    • 1 <= nums[i] <= 10^8
    • 1 <= value <= 10^8
    • At most 50000 calls will be made to showFirstUnique and add.

    Come from: https://leetcode.com/explore/challenge/card/30-day-leetcoding-challenge/531/week-4/3313/

    1. class FirstUnique {
    2. public:
    3. struct Node{
    4. int val;
    5. Node *prev;
    6. Node *next;
    7. Node(int value): val(value), prev(NULL), next(NULL){};
    8. };
    9. map<int, Node*>unique;
    10. set<int>store;
    11. Node *begin;
    12. Node *end;
    13. FirstUnique(vector<int>& nums) {
    14. begin = new Node(-1);
    15. end = new Node(-1);
    16. begin->next = end;
    17. end->prev = begin;
    18. for(auto &index : nums)
    19. {
    20. if(store.find(index) == store.end())
    21. {
    22. Node *cur = new Node(index);
    23. unique[index] = cur;
    24. Node *pre = end->prev;
    25. pre->next = cur;
    26. cur->prev = pre;
    27. cur->next = end;
    28. end->prev = cur;
    29. store.insert(index);
    30. }
    31. else
    32. {
    33. if(unique.find(index) != unique.end())
    34. {
    35. Node *cur = unique[index];
    36. unique.erase(index);
    37. Node *pre = cur->prev;
    38. Node *nex = cur->next;
    39. pre->next = nex;
    40. nex->prev = pre;
    41. delete cur;
    42. }
    43. }
    44. }
    45. }
    46. int showFirstUnique() {
    47. if(!unique.empty())
    48. return begin->next->val;
    49. else
    50. return -1;
    51. }
    52. void add(int value) {
    53. if(store.find(value) == store.end())
    54. {
    55. Node *cur = new Node(value);
    56. unique[value] = cur;
    57. Node *pre = end->prev;
    58. pre->next = cur;
    59. cur->prev = pre;
    60. cur->next = end;
    61. end->prev = cur;
    62. store.insert(value);
    63. }
    64. else
    65. {
    66. if(unique.find(value) != unique.end())
    67. {
    68. Node *cur = unique[value];
    69. unique.erase(value);
    70. Node *pre = cur->prev;
    71. Node *nex = cur->next;
    72. pre->next = nex;
    73. nex->prev = pre;
    74. delete cur;
    75. }
    76. }
    77. }
    78. };
    79. /**
    80. * Your FirstUnique object will be instantiated and called as such:
    81. * FirstUnique* obj = new FirstUnique(nums);
    82. * int param_1 = obj->showFirstUnique();
    83. * obj->add(value);
    84. */

    提交的结果如下,貌似占用了很大的内存。
    image.png

    题目总共提供了三种思路,双端链表是其中最容易想到的一种思路

    Note1: Use doubly Linked list with hashmap of pointers to linked list nodes. add unique number to the linked list. When add is called check if the added number is unique then it have to be added to the linked list and if it is repeated remove it from the linked list if exists. When showFirstUnique is called retrieve the head of the linked list.


    Note2: Use queue and check that first element of the queue is always unique.


    Note3: Use set or heap to make running time of each function O(logn).