217存在重复元素![J(9(APQ~M@8IC7(V_NVVF3.pngX@ONV_1K%E3B8~Q$_R7$E9T.png

思路:

数组存在重复元素,可以将数组排序,然后再遍历判断,但是这样的复杂度是 NlogNNlogN,但是,一般会选择牺牲空间保时间,所以使用哈希表来解决这道题,让时间复杂度为 NN。

流程如下:
创建一个哈希表,然后从左往右遍历数组。
检测哈希表中是否已存在当前字符,若存在,直接返回结果,若不存在,将当前字符加入哈希表,供后续判断使用即可。

代码

  1. class Solution {
  2. public boolean containsDuplicate(int[] nums) {
  3. Set<Integer> set = new HashSet<Integer>();
  4. for (int x : nums) {
  5. if (!set.add(x)) {
  6. return true;
  7. }
  8. }
  9. return false;
  10. }
  11. }
  1. #使用set()
  2. class Solution:
  3. def containsDuplicate(self, nums: List[int]) -> bool:
  4. nlen = len(nums)
  5. if not nlen:return False
  6. nums.sort()
  7. l = [nums[0]]
  8. for i in range(1,nlen):
  9. if l[-1] ^ nums[i] != 0:
  10. l.append(nums[i])
  11. else:
  12. return True
  13. return False
  14. #排序并比较相邻元素是否相同class Solution:
  15. def containsDuplicate(self, nums: List[int]) -> bool:
  16. nlen = len(nums)
  17. if nlen != len(set(nums)):
  18. return True
  19. return False

705设计哈希集合![]R35BAF~1L1484HTZ]T9T7.pngR_X{DTSGDO$76@7MIMLB5]5.png

思路

java:
简单数组
题目给出了 0 <= key <= 10^6 数据范围,同时限定了 key 只能是 int。
可以直接使用一个 boolean 数组记录某个 key 是否存在,key 直接对应 boolean 的下标。

链表

python:
哈希函数中的键值一般要%于一个底数,底数一般为素数,题目指出最多调用次数为10^4, 所以底数一般为三到四位数的素数即可,巧用Python的二维数组

代码

  1. class MyHashSet {
  2. boolean[] nodes = new boolean[1000009];
  3. public void add(int key) {
  4. nodes[key] = true;
  5. }
  6. public void remove(int key) {
  7. nodes[key] = false;
  8. }
  9. public boolean contains(int key) {
  10. return nodes[key];
  11. }
  12. }
  13. class MyHashSet {
  14. // 由于使用的是「链表」,这个值可以取得很小
  15. Node[] nodes = new Node[10009];
  16. public void add(int key) {
  17. // 根据 key 获取哈希桶的位置
  18. int idx = getIndex(key);
  19. // 判断链表中是否已经存在
  20. Node loc = nodes[idx], tmp = loc;
  21. if (loc != null) {
  22. Node prev = null;
  23. while (tmp != null) {
  24. if (tmp.key == key) {
  25. return;
  26. }
  27. prev = tmp;
  28. tmp = tmp.next;
  29. }
  30. tmp = prev;
  31. }
  32. Node node = new Node(key);
  33. // 头插法
  34. // node.next = loc;
  35. // nodes[idx] = node;
  36. // 尾插法
  37. if (tmp != null) {
  38. tmp.next = node;
  39. } else {
  40. nodes[idx] = node;
  41. }
  42. }
  43. public void remove(int key) {
  44. int idx = getIndex(key);
  45. Node loc = nodes[idx];
  46. if (loc != null) {
  47. Node prev = null;
  48. while (loc != null) {
  49. if (loc.key == key) {
  50. if (prev != null) {
  51. prev.next = loc.next;
  52. } else {
  53. nodes[idx] = loc.next;
  54. }
  55. return;
  56. }
  57. prev = loc;
  58. loc = loc.next;
  59. }
  60. }
  61. }
  62. public boolean contains(int key) {
  63. int idx = getIndex(key);
  64. Node loc = nodes[idx];
  65. if (loc != null) {
  66. while (loc != null) {
  67. if (loc.key == key) {
  68. return true;
  69. }
  70. loc = loc.next;
  71. }
  72. }
  73. return false;
  74. }
  75. static class Node {
  76. private int key;
  77. private Node next;
  78. private Node(int key) {
  79. this.key = key;
  80. }
  81. }
  82. int getIndex(int key) {
  83. // 因为 nodes 的长度只有 10009,对应的十进制的 10011100011001(总长度为 32 位,其余高位都是 0)
  84. // 为了让 key 对应的 hash 高位也参与运算,这里对 hashCode 进行右移异或
  85. // 使得 hashCode 的高位随机性和低位随机性都能体现在低 16 位中
  86. int hash = Integer.hashCode(key);
  87. hash ^= (hash >>> 16);
  88. return hash % nodes.length;
  89. }
  90. }
  1. class MyHashSet:
  2. def __init__(self):
  3. self.base = 799
  4. self.hash_set = [[] for i in range(self.base)]
  5. def hash_key(self, key: int):
  6. return key%self.base
  7. def add(self, key: int) -> None:
  8. hash_pos = self.hash_key(key)
  9. if key in self.hash_set[hash_pos]:
  10. pass
  11. else:
  12. self.hash_set[hash_pos].append(key)
  13. def remove(self, key: int) -> None:
  14. hash_pos = self.hash_key(key)
  15. if key not in self.hash_set[hash_pos]:
  16. pass
  17. else:
  18. self.hash_set[hash_pos].remove(key)
  19. def contains(self, key: int) -> bool:
  20. hash_pos = self.hash_key(key)
  21. if key in self.hash_set[hash_pos]:
  22. return True
  23. else:
  24. return False
  25. # Your MyHashSet object will be instantiated and called as such:
  26. # obj = MyHashSet()
  27. # obj.add(key)
  28. # obj.remove(key)
  29. # param_3 = obj.contains(key)