• LeetCode 705. Design HashSet


    Design a HashSet without using any built-in hash table libraries.

    Implement MyHashSet class:

    • void add(key) Inserts the value key into the HashSet.
    • bool contains(key) Returns whether the value key exists in the HashSet or not.
    • void remove(key) Removes the value key in the HashSet. If key does not exist in the HashSet, do nothing.

    Example 1:

    Input
    ["MyHashSet", "add", "add", "contains", "contains", "add", "contains", "remove", "contains"]
    [[], [1], [2], [1], [3], [2], [2], [2], [2]]
    Output
    [null, null, null, true, false, null, true, null, false]
    
    Explanation
    MyHashSet myHashSet = new MyHashSet();
    myHashSet.add(1);      // set = [1]
    myHashSet.add(2);      // set = [1, 2]
    myHashSet.contains(1); // return True
    myHashSet.contains(3); // return False, (not found)
    myHashSet.add(2);      // set = [1, 2]
    myHashSet.contains(2); // return True
    myHashSet.remove(2);   // set = [1]
    myHashSet.contains(2); // return False, (already removed)

    Constraints:

    • 0 <= key <= 106
    • At most 104 calls will be made to addremove, and contains.

    设计一个hashset。复习了一下hashtable的basics吧。几个要素:

    1. hash function,如果用简单的取%的话最好取prime number

    2. capacity,就是这个数组长度

    3. load factor,当数组里超过一定数量百分比的index已经被放入了元素,那就需要capacity * 2并进行rehash来把原来数组里的元素重新hash到新的数组

    4. collision handling,open addressing和chaining两种方式,一个是沿着数组接着找下一个空的,一个是用一个linkedlist来存hash到同一个index的元素

    这题写的时候就用了一个array of LinkedList来存放元素,实现了rehash的功能。还需要记录一个count表示已经放了多少元素,用来判断rehash的条件。每次add的时候先rehash再加。

    这里还有一个小坑,被卡了好久。在取array里面一个list的时候,如果取成一个新的变量,然后对这个变量进行修改,其实改不到原来的数组里的那个值,因为它相当于是一份copy of content,not reference。(应该是吧,至少现在试出来是这样)

    1. class MyHashSet {
    2. int capacity = 2;
    3. double loadFactor = 0.75;
    4. List<Integer>[] lists;
    5. int count = 0;
    6. public MyHashSet() {
    7. lists = new LinkedList[capacity];
    8. }
    9. public void add(int key) {
    10. if (contains(key)) {
    11. return;
    12. }
    13. if (count > capacity * loadFactor) {
    14. capacity *= 2;
    15. List<Integer>[] old = lists;
    16. lists = new LinkedList[capacity];
    17. for (List<Integer> list : old) {
    18. if (list != null) {
    19. for (int i : list) {
    20. add(i);
    21. }
    22. }
    23. }
    24. }
    25. if (lists[hash(key)] == null) {
    26. lists[hash(key)] = new LinkedList<>();
    27. }
    28. lists[hash(key)].add(key); // must use lists[hash(key)]
    29. count++;
    30. }
    31. public void remove(int key) {
    32. if (!contains(key)) {
    33. return;
    34. }
    35. List<Integer> list = lists[hash(key)];
    36. for (int i = 0; i < list.size(); i++) {
    37. if (list.get(i) == key) {
    38. list.remove(i);
    39. count--;
    40. }
    41. }
    42. }
    43. public boolean contains(int key) {
    44. List<Integer> list = lists[hash(key)];
    45. if (list != null) {
    46. for (int i = 0; i < list.size(); i++) {
    47. if (list.get(i) == key) {
    48. return true;
    49. }
    50. }
    51. }
    52. return false;
    53. }
    54. private int hash(int i) {
    55. return i % capacity;
    56. }
    57. }
    58. /**
    59. * Your MyHashSet object will be instantiated and called as such:
    60. * MyHashSet obj = new MyHashSet();
    61. * obj.add(key);
    62. * obj.remove(key);
    63. * boolean param_3 = obj.contains(key);
    64. */

  • 相关阅读:
    Dell戴尔笔记本外星人Alienware x15 R2原装出厂Windows11系统21H2
    813. 最大平均值和的分组
    Spring学习 | Spring简介&IOC简介
    给虚拟机配置固定局域网IP
    java计算机毕业设计springboot+vue线上教学辅助系统
    企业如何保护机密文件安全
    C语言第四章第5节条件运算符和条件表达式学习导案
    redis 分布式锁
    jmeter做压测
    【基于HTML5的网页设计及应用】——float实现页面布局
  • 原文地址:https://blog.csdn.net/qq_37333947/article/details/127735950