当前位置:   article > 正文

【哈希表】(三) 实际应用 - 哈希映射

哈希映射

目录

一、哈希映射 - 用法

二、场景 I - 提供更多信息

三、两数之和

3.1 题目要求

3.2 解决过程

四、同构字符串

4.1 题目要求

4.2 解决过程

四、两个列表的最小索引总和

4.1 题目要求

4.2 解决过程

六、场景 II - 按键聚合

七、字符串中的第一个唯一字符

7.1 题目要求

7.2 解决过程

八、两个数组的交集 II

8.1 题目要求

8.2 解决过程

九、存在重复元素 II

9.1 题目要求

9.2 解决过程

十、日志速率限制器 (PLUS 会员专享)


参考文献:https://leetcode-cn.com/leetbook/read/hash-table/xhly3j/ 


一、哈希映射 - 用法

  1. // C++ implementation
  2. #include <unordered_map> // 0. include the library
  3. int main() {
  4. // 1. initialize a hash map
  5. unordered_map<int, int> hashmap;
  6. // 2. insert a new (key, value) pair
  7. hashmap.insert(make_pair(0, 0));
  8. hashmap.insert(make_pair(2, 3));
  9. // 3. insert a new (key, value) pair or update the value of existed key
  10. hashmap[1] = 1;
  11. hashmap[1] = 2;
  12. // 4. get the value of a specific key
  13. cout << "The value of key 1 is: " << hashmap[1] << endl;
  14. // 5. delete a key
  15. hashmap.erase(2);
  16. // 6. check if a key is in the hash map
  17. if (hashmap.count(2) <= 0) {
  18. cout << "Key 2 is not in the hash map." << endl;
  19. }
  20. // 7. get the size of the hash map
  21. cout << "the size of hash map is: " << hashmap.size() << endl;
  22. // 8. iterate the hash map
  23. for (auto it = hashmap.begin(); it != hashmap.end(); ++it) {
  24. cout << "(" << it->first << "," << it->second << ") ";
  25. }
  26. cout << "are in the hash map." << endl;
  27. // 9. clear the hash map
  28. hashmap.clear();
  29. // 10. check if the hash map is empty
  30. if (hashmap.empty()) {
  31. cout << "hash map is empty now!" << endl;
  32. }
  33. }
  1. # Python implementation
  2. # 1. initialize a hash map
  3. hashmap = {0 : 0, 2 : 3}
  4. # 2. insert a new (key, value) pair or update the value of existed key
  5. hashmap[1] = 1
  6. hashmap[1] = 2
  7. # 3. get the value of a key
  8. print("The value of key 1 is: " + str(hashmap[1]))
  9. # 4. delete a key
  10. del hashmap[2]
  11. # 5. check if a key is in the hash map
  12. if 2 not in hashmap:
  13. print("Key 2 is not in the hash map.")
  14. # 6. both key and value can have different type in a hash map
  15. hashmap["pi"] = 3.1415
  16. # 7. get the size of the hash map
  17. print("The size of hash map is: " + str(len(hashmap)))
  18. # 8. iterate the hash map
  19. for key in hashmap:
  20. print("(" + str(key) + "," + str(hashmap[key]) + ")", end=" ")
  21. print("are in the hash map.")
  22. # 9. get all keys in hash map
  23. print(hashmap.keys())
  24. # 10. clear the hash map
  25. hashmap.clear();
  26. print("The size of hash map is: " + str(len(hashmap)))

 参考文献:https://leetcode-cn.com/leetbook/read/hash-table/xhy35e/


 

二、场景 I - 提供更多信息

  1. // C++ implementation
  2. /*
  3. * Template for using hash map to find duplicates.
  4. * Replace ReturnType with the actual type of your return value.
  5. */
  6. ReturnType aggregateByKey_hashmap(vector<Type>& keys) {
  7. // Replace Type and InfoType with actual type of your key and value
  8. unordered_map<Type, InfoType> hashtable;
  9. for (Type key : keys) {
  10. if (hashmap.count(key) > 0) {
  11. if (hashmap[key] satisfies the requirement) {
  12. return needed_information;
  13. }
  14. }
  15. // Value can be any information you needed (e.g. index)
  16. hashmap[key] = value;
  17. }
  18. return needed_information;
  19. }

 参考文献:https://leetcode-cn.com/leetbook/read/hash-table/xhcuhg/


三、两数之和

3.1 题目要求

3.2 解决过程

个人实现

法一:朴素法 - 暴力迭代法。空间复杂度 O(1),时间复杂度 O(n²)。

2020/08/21 - 26.06% (3552ms)

  1. class Solution:
  2. def twoSum(self, nums: List[int], target: int) -> List[int]:
  3. for i in range(len(nums)-1): # 当前数值
  4. cur = target - nums[i] # 待寻找数值
  5. for j in range(i+1, len(nums)): # 被比较数值
  6. if cur == nums[j]:
  7. return [i, j]

法二:散列表 / 哈希表。牺牲空间换取时间。结合题目和提示可使用字典形式的哈希表实现 (当然,由全0初始化列表构造的 HashTable 亦可)。

具体而言,先用 target 减去列表中的首个元素值,并将该元素值作为 key、元素值的下标/索引作为 value 存入字典。接着 target 依次减去列表中的其余元素值,并判断差是否作为 key 存在于字典中。若存在,则表示列表中存在两值之和等于 target,此时可直接返回答案,即 key 对应的 value 及当前元素值的 index。若不存在,则同理将该元素值及其索引作为 <key, value> 存入字典。通过字典存储可以实现去重。空间复杂度 O(n),时间复杂度 O(n)。

2020/08/21 - 97.22% (56ms) - 最佳

  1. class Solution:
  2. def twoSum(self, nums: List[int], target: int) -> List[int]:
  3. hashmap = {} # 字典形式的 hashmap (使用全0初始化的列表也可以)
  4. for index, num in enumerate(nums):
  5. cur = target-num
  6. if cur in hashmap:
  7. return [hashmap[cur], index] # 找到两数之和满足, 返回二者 index
  8. else:
  9. hashmap[num] = index # 否则, 将当前元素及其索引作为 key-value 加入 hashmap

判断值是否在某个容器 (container) 中,能做到 O(1) 时间复杂度查找 的便是最常用的 散列表 (HashTable), Python 内置数据类型中的字典即是。就本题而言,key 为标记元素值,value 为元素值下标/索引,所以更加确定使用字典这个数据结构。

此外,若使用 Python 内置 index() 函数,则因其复杂度为 O(n) 将使整个程序的复杂度达到 O(n²) (结合外层 for 循环的 O(n));若选择使用两个 for 循环,则虽然能取得 O(1) 的空间复杂度,但却将达到 O(n²) 的时间复杂度;此二者均为低效的解法,而使用散列表则能够实现 牺牲空间换取时间,且实际中能找到节省时间的解往往更有价值。

参考文献

https://leetcode-cn.com/problems/two-sum/submissions/


 

四、同构字符串

4.1 题目要求

4.2 解决过程

个人实现

法一:哈希映射。分别记录 s 和 t 的各字符及其位置索引到哈希映射 (dict) 中,然后一一比较各 key 的 value 是否一致。关于 zip() 函数 的使用详见 链接。空间复杂度 O(n),时间复杂度 O(n)。

2020/08/25 - 81.63% (48ms)

  1. class Solution:
  2. def isIsomorphic(self, s: str, t: str) -> bool:
  3. hashmap_s = {} # s 的哈希映射表
  4. hashmap_t = {} # t 的哈希映射表
  5. # 添加各字符及其位置索引到哈希映射表中
  6. for i in range(len(s)):
  7. # 把 s 的单字符 s[i] 作为 key, 位置索引 i 作为 value
  8. if not hashmap_s.get(s[i]):
  9. hashmap_s[s[i]] = [i]
  10. else:
  11. hashmap_s[s[i]].append(i)
  12. # 把 t 的单字符 t[i] 作为 key, 位置索引 i 作为 value
  13. if not hashmap_t.get(t[i]):
  14. hashmap_t[t[i]] = [i]
  15. else:
  16. hashmap_t[t[i]].append(i)
  17. # 根据哈希映射表, 逐对比较位置索引列表是否一致 (不能直接比较 dict.values() 因为无序)
  18. for keys in zip(hashmap_s.keys(), hashmap_t.keys()):
  19. if hashmap_s[keys[0]] != hashmap_t[keys[1]]:
  20. return False
  21. return True

法一改:哈希映射。不仅使用 默认字典 类型来简化书写,还改为在添加位置索引后就进行比较。因为对于同构字符串,其每次添加单个字符作为 key 后,key 对应的索引列表 value 必定一致,否则不为同构字符串。关于 collections.default 详见 链接。空间复杂度 O(n),时间复杂度 O(n)。

2020/08/25 - 97.50% (40ms) - 最佳

  1. class Solution:
  2. def isIsomorphic(self, s: str, t: str) -> bool:
  3. # 使用默认字典 defaultdict 简化书写
  4. hashmap_s = collections.defaultdict(list) # s 的哈希映射表(默认类型为list的默认字典)
  5. hashmap_t = collections.defaultdict(list) # t 的哈希映射表(默认类型为list的默认字典)
  6. # 添加各字符及其位置索引到哈希映射表中
  7. for i in range(len(s)):
  8. # 每添加一次索引
  9. hashmap_s[s[i]].append(i)
  10. hashmap_t[t[i]].append(i)
  11. # 就比较一次索引
  12. if hashmap_s[s[i]] != hashmap_t[t[i]]:
  13. return False
  14. return True

法二:内置函数组合。关于单星号操作符 * 详见 链接;关于高阶函数 map() 详见 链接

2020/08/25 - 91.95% (44ms)

  1. class Solution:
  2. def isIsomorphic(self, s: str, t: str) -> bool:
  3. #return [*map(s.index, s)] == [*map(t.index, t)]
  4. return list(map(s.index, s)) == list(map(t.index, t))

当然,实质上并不推荐使用 Python 高阶函数解题,一是不好分析复杂度,二是缺乏通用性

参考文献

https://leetcode-cn.com/leetbook/read/hash-table/xhjvbj/


四、两个列表的最小索引总和

4.1 题目要求

4.2 解决过程

个人实现

法一:哈希映射。先将 list1 中各元素 - 饭店名作为 key,索引作为 value 保存在哈希映射中。然后新建遍历 min_index 用于维护最小索引组合,min_place 则为最小索引组合对应饭店名列表。接着,遍历 list2 一一查找、比较和更新结果。最终,返回 min_place。

空间复杂度 O(len(list1) × len(str_avg)),其中 len(list1) 是 list1 长度,len(str_avg) 是 list1 中字符串平均长度。

时间复杂度 O(len(list1) × len(list2)),其中 len(list1) 是 list1 长度,len(list2) 是 list2 长度。

2020/08/25 - 98.25% (172ms) - 最佳

  1. class Solution:
  2. def findRestaurant(self, list1: List[str], list2: List[str]) -> List[str]:
  3. # 将 list1 中各元素 - 饭店名作为 key, 索引作为 value 保存在哈希映射中
  4. hashmap = {}
  5. for i in range(len(list1)):
  6. hashmap[list1[i]] = i
  7. min_index = float("Inf") # 当前最小索引组合
  8. min_place = [] # 当前最小索引餐厅
  9. for j in range(len(list2)):
  10. index = hashmap.get(list2[j]) # 提取索引 index
  11. if index is not None: # 若存在索引 index, 则表明有共同喜爱的餐厅
  12. new_index = index + j # 当前新索引
  13. if min_index == new_index:
  14. min_place.append(list2[j]) # 补增餐厅名
  15. elif min_index > new_index:
  16. min_index = new_index # 更新最小索引组合
  17. min_place = [list2[j]] # 更新最小索引餐厅
  18. return min_place

 参考文献

https://leetcode-cn.com/leetbook/read/hash-table/xhfact/

https://leetcode-cn.com/problems/minimum-index-sum-of-two-lists/solution/liang-ge-lie-biao-de-zui-xiao-suo-yin-zong-he-by-l/


六、场景 II - 按键聚合

  1. // C++ implementation
  2. /*
  3. * Template for using hash map to find duplicates.
  4. * Replace ReturnType with the actual type of your return value.
  5. */
  6. ReturnType aggregateByKey_hashmap(vector<Type>& keys) {
  7. // Replace Type and InfoType with actual type of your key and value
  8. unordered_map<Type, InfoType> hashtable;
  9. for (Type key : keys) {
  10. if (hashmap.count(key) > 0) {
  11. update hashmap[key];
  12. }
  13. // Value can be any information you needed (e.g. index)
  14. hashmap[key] = value;
  15. }
  16. return needed_information;
  17. }

参考文献:https://leetcode-cn.com/leetbook/read/hash-table/xxhryr/


七、字符串中的第一个唯一字符

7.1 题目要求

7.2 解决过程

个人实现

法一:哈希映射。先遍历字符串,将各字符及其位置索引加入哈希映射。然后遍历哈希映射表的键,输出首个单次出现的字符索引,否则输出 -1。空间复杂度 O(n),时间复杂度 O(n)。

2020/08/25 - 37.03% (164ms)

  1. class Solution:
  2. def firstUniqChar(self, s: str) -> int:
  3. # key=char : value=index
  4. hashmap = {}
  5. # 遍历字符串, 将各字符及其索引加入哈希映射中
  6. for i in range(len(s)):
  7. if hashmap.get(s[i]) is None:
  8. hashmap[s[i]] = [i]
  9. else:
  10. hashmap[s[i]].append(i)
  11. # 遍历哈希映射表的键, 输出首个单次出现的字符索引
  12. for j in hashmap.keys():
  13. if len(hashmap[j]) == 1:
  14. return hashmap[j][0]
  15. return -1

法一改:哈希映射。使用默认字典简化书写。关于 collections.default 详见 链接。空间复杂度 O(n),时间复杂度 O(n)。

2020/08/25 - 65.93% (124ms) - 快了不少

  1. class Solution:
  2. def firstUniqChar(self, s: str) -> int:
  3. # key=char : value=index
  4. hashmap = collections.defaultdict(list)
  5. for i in range(len(s)):
  6. hashmap[s[i]].append(i)
  7. for j in hashmap.keys():
  8. if len(hashmap[j]) == 1:
  9. return hashmap[j][0]
  10. return -1

 法二:哈希映射计数器。关于 collections.Counter 详见 链接。空间复杂度 O(n),时间复杂度 O(n)。

2020/08/25 - 83.80% (104ms) - 快了更多

  1. class Solution:
  2. def firstUniqChar(self, s: str) -> int:
  3. counter = collections.Counter(s)
  4. for i in range(len(s)):
  5. if counter[s[i]] == 1: # 如果遇到首个仅出现单次的字符
  6. return i # 即为目标字符, 返回其索引
  7. return -1


其他实现与说明

  1. class Solution(object):
  2. def firstUniqChar(self, s: str) -> int:
  3. # 先假设最小索引为最后的字符索引
  4. min_unique_char_index = len(s)
  5. # 已知字符串由小写字母构成,则遍历a-z
  6. for c in "abcdefghijklmnopqrstuvwxyz":
  7. i = s.find(c)
  8. # 分别从目标的字符串头和字符串尾查找对应字母的索引;如果两索引相等,则说明是单一字符
  9. if i != -1 and i == s.rfind(c):
  10. # 更新最新的最小索引
  11. min_unique_char_index = min(min_unique_char_index, i)
  12. # 如果返回值不为最后字符的索引,则返回最小索引值
  13. # 否则,根据题意,返回-1
  14. return min_unique_char_index if min_unique_char_index != len(s) else -1

2020/08/25 - 99.94% (36ms) - 最佳 - 虽然很快,但内置函数的使用还是要慎重

以下实现表面上看起来更简单,但实际性能差很多,只有约 60%:

  1. class Solution(object):
  2. def firstUniqChar(self, s: str) -> int:
  3. for c in s:
  4. index = s.find(c)
  5. if index == s.rfind(c):
  6. return index
  7. return -1

  1. class Solution(object):
  2. def firstUniqChar(self, s: str) -> int:
  3. odict = collections.OrderedDict()
  4. # 记录字符出现次数
  5. for c in s:
  6. odict[c] = odict[c] + 1 if c in odict else 1
  7. # 利用有序的特性,在字典中找出首个出现次数为一的字符串
  8. for k, v in odict.items():
  9. if v == 1:
  10. # 返回字符串首次出现的位置
  11. return s.index(k)
  12. return -1

 2020/08/25 - 65.93% (124ms)

以上实现虽然还行,但尽量不使用其他内置函数为妙。 

参考文献

https://leetcode-cn.com/leetbook/read/hash-table/xxx94s/

https://leetcode-cn.com/problems/first-unique-character-in-a-string/solution/zi-fu-chuan-zhong-de-di-yi-ge-wei-yi-zi-fu-by-leet/

https://leetcode-cn.com/problems/first-unique-character-in-a-string/solution/python-4chong-fang-fa-yi-ge-12msde-gai-jin-jie-fa-/


 

八、两个数组的交集 II

8.1 题目要求

8.2 解决过程

个人实现

法一:哈希映射。空间复杂度 O(n),时间复杂度 O(n)。

2020/08/25 - 92.19% (56ms)

  1. class Solution:
  2. def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
  3. # nums1 元素计数器 - dict 实现
  4. hashmap = {}
  5. for i in range(len(nums1)):
  6. if hashmap.get(nums1[i]) is None:
  7. hashmap[nums1[i]] = 0 # 零值初始化
  8. hashmap[nums1[i]] += 1 # 计数+1
  9. result = []
  10. for j in range(len(nums2)):
  11. if hashmap.get(nums2[j]): # 计数非空非零
  12. result.append(nums2[j]) # 结果添加
  13. hashmap[nums2[j]] -= 1 # 计数-1
  14. return result

法一改:哈希映射。使用默认字典简化书写。关于 collections.default 详见 链接。空间复杂度 O(n),时间复杂度 O(n)。

2020/08/25 - 92.19% (56ms)

  1. class Solution:
  2. def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
  3. # nums1 元素计数器 - defaultdict 实现
  4. hashmap = collections.defaultdict(int)
  5. for i in range(len(nums1)):
  6. hashmap[nums1[i]] += 1 # 计数+1
  7. result = []
  8. for j in range(len(nums2)):
  9. if hashmap.get(nums2[j]): # 计数非空非零
  10. result.append(nums2[j]) # 结果添加
  11. hashmap[nums2[j]] -= 1 # 计数-1
  12. return result

法一改:哈希映射计数器。关于 collections.Counter 详见 链接。空间复杂度 O(n),时间复杂度 O(n)。

2020/08/25 - 80.74% (60ms)

  1. class Solution:
  2. def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
  3. # nums1 元素计数器 - Counter 实现
  4. hashmap = collections.Counter(nums1)
  5. result = [] # 结果列表
  6. for j in range(len(nums2)):
  7. n = nums2[j] # 当前数字
  8. if hashmap.get(n): # 计数非空非零
  9. result.append(n) # 结果添加
  10. hashmap[n] -= 1 # 计数-1
  11. return result

甚至可以更多地使用 Counter 特性完成:

  1. class Solution:
  2. def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
  3. num1 = collections.Counter(nums1)
  4. num2 = collections.Counter(nums2)
  5. num = num1 & num2
  6. return num.elements()

 法三:数组排序 + 双指针。空间复杂度 O(n),时间复杂度 O(nlong)。

2020/08/25 - 63.67% (64ms)

  1. class Solution:
  2. def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
  3. nums1.sort() # nums1 排序
  4. nums2.sort() # nums2 排序
  5. result = [] # 结果列表
  6. ptr1 = 0 # nums1 指针
  7. ptr2 = 0 # nums2 指针
  8. while ptr1 < len(nums1) and ptr2 < len(nums2):
  9. n1 = nums1[ptr1] # 当前 nums1 元素
  10. n2 = nums2[ptr2] # 当前 nums2 元素
  11. if n1 == n2:
  12. result.append(n1)
  13. ptr1 += 1
  14. ptr2 += 1
  15. elif n1 > n2:
  16. ptr2 += 1
  17. else:
  18. ptr1 += 1
  19. return result

官方实现与说明

fig1

  1. class Solution:
  2. def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
  3. if len(nums1) > len(nums2):
  4. return self.intersect(nums2, nums1) # 强行令短左长右
  5. m = collections.Counter()
  6. for num in nums1:
  7. m[num] += 1
  8. intersection = list()
  9. for num in nums2:
  10. if (count := m.get(num, 0)) > 0: # := 是海象运算符
  11. intersection.append(num)
  12. m[num] -= 1
  13. if m[num] == 0:
  14. m.pop(num)
  15. return intersection

2020/08/25 - 80.74% (60ms) 


  1. class Solution:
  2. def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
  3. nums1.sort()
  4. nums2.sort()
  5. length1, length2 = len(nums1), len(nums2)
  6. intersection = list()
  7. index1 = index2 = 0
  8. while index1 < length1 and index2 < length2:
  9. if nums1[index1] < nums2[index2]:
  10. index1 += 1
  11. elif nums1[index1] > nums2[index2]:
  12. index2 += 1
  13. else:
  14. intersection.append(nums1[index1])
  15. index1 += 1
  16. index2 += 1
  17. return intersection

参考文献

https://leetcode-cn.com/leetbook/read/hash-table/xx5hsd/

https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/solution/liang-ge-shu-zu-de-jiao-ji-ii-by-leetcode-solution/

https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/solution/jin-jie-san-wen-by-user5707f/


九、存在重复元素 II

9.1 题目要求

9.2 解决过程

个人实现

法一:哈希映射。用哈希表记录当前数字最后一次遇到时的索引,然后根据条件要求判断或更新。空间复杂度 O(n),时间复杂度 O(n)。

2020/08/25 - 89.02% (44ms) - 最佳

  1. class Solution:
  2. def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
  3. # key=num : value=index
  4. hashmap = {}
  5. for i in range(len(nums)):
  6. index = hashmap.get(nums[i])
  7. if (index is None) or (i-index > k): # (abs(index-i) > k) 由于后来的肯定比之前的 index 大, 故 abs() 可不用
  8. hashmap[nums[i]] = i # 当前数字索引为空(尚未记录)或不符合要求, 则更新之
  9. else:
  10. return True
  11. return False

官方实现与说明

  1. // Java implementation
  2. public boolean containsNearbyDuplicate(int[] nums, int k) {
  3. for (int i = 0; i < nums.length; ++i) {
  4. for (int j = Math.max(i - k, 0); j < i; ++j) {
  5. if (nums[i] == nums[j]) return true;
  6. }
  7. }
  8. return false;
  9. }
  10. // Time Limit Exceeded.


  1. // Java implementation
  2. public boolean containsNearbyDuplicate(int[] nums, int k) {
  3. Set<Integer> set = new TreeSet<>();
  4. for (int i = 0; i < nums.length; ++i) {
  5. if (set.contains(nums[i])) return true;
  6. set.add(nums[i]);
  7. if (set.size() > k) {
  8. set.remove(nums[i - k]);
  9. }
  10. }
  11. return false;
  12. }
  13. // Time Limit Exceeded.


  1. // Java implementation
  2. public boolean containsNearbyDuplicate(int[] nums, int k) {
  3. Set<Integer> set = new HashSet<>();
  4. for (int i = 0; i < nums.length; ++i) {
  5. if (set.contains(nums[i])) return true;
  6. set.add(nums[i]);
  7. if (set.size() > k) {
  8. set.remove(nums[i - k]);
  9. }
  10. }
  11. return false;
  12. }
  1. # Python implementation
  2. class Solution:
  3. def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
  4. # 维护一个 k 长度的哈希集合
  5. hashset = set()
  6. for i in range(len(nums)):
  7. # 若当前数字存在于哈希集合中, 则满足条件
  8. if nums[i] in hashset:
  9. return True
  10. # 否则, 将当前数字存入哈希集合
  11. hashset.add(nums[i])
  12. # 哈希集合超长时, 剔除最早进入的数字
  13. if len(hashset) > k:
  14. hashset.remove(nums[i-k])
  15. return False

 2020/08/25 - 76.34% (48ms)

参考文献

https://leetcode-cn.com/leetbook/read/hash-table/xx5bzh/

https://leetcode-cn.com/problems/contains-duplicate-ii/solution/cun-zai-zhong-fu-yuan-su-ii-by-leetcode/


十、日志速率限制器 (PLUS 会员专享)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/350843
推荐阅读
相关标签
  

闽ICP备14008679号