• hash表 算法模板和相关题目


    706. 设计哈希映射

    难度简单

    不使用任何内建的哈希表库设计一个哈希映射

    具体地说,你的设计应该包含以下的功能

    • put(key, value):向哈希映射中插入(键,值)的数值对。如果键对应的值已经存在,更新这个值。
    • get(key):返回给定的键所对应的值,如果映射中不包含这个键,返回-1。
    • remove(key):如果映射中存在这个键,删除这个数值对。


    示例:

    MyHashMap hashMap = new MyHashMap();
    hashMap.put(1, 1);          
    hashMap.put(2, 2);         
    hashMap.get(1);            // 返回 1
    hashMap.get(3);            // 返回 -1 (未找到)
    hashMap.put(2, 1);         // 更新已有的值
    hashMap.get(2);            // 返回 1 
    hashMap.remove(2);         // 删除键为2的数据
    hashMap.get(2);            // 返回 -1 (未找到) 
    


    注意:

    • 所有的值都在 [0, 1000000]的范围内。
    • 操作的总数目在[1, 10000]范围内。
    • 不要使用内建的哈希库。
     1 class Bucket:
     2     def __init__(self):
     3         self.bucket = []
     4 
     5     def get(self, key):
     6         for (k, v) in self.bucket:
     7             if k == key:
     8                 return v
     9         return -1
    10 
    11     def update(self, key, value):
    12         found = False
    13         for i, kv in enumerate(self.bucket):
    14             if key == kv[0]:
    15                 self.bucket[i] = (key, value)
    16                 found = True
    17                 break
    18 
    19         if not found:
    20             self.bucket.append((key, value))
    21 
    22     def remove(self, key):
    23         for i, kv in enumerate(self.bucket):
    24             if key == kv[0]:
    25                 del self.bucket[i]
    26 
    27 
    28 class MyHashMap(object):
    29 
    30     def __init__(self):
    31         """
    32         Initialize your data structure here.
    33         """
    34         # better to be a prime number, less collision
    35         self.key_space = 2069
    36         self.hash_table = [Bucket() for i in range(self.key_space)]
    37 
    38 
    39     def put(self, key, value):
    40         """
    41         value will always be non-negative.
    42         :type key: int
    43         :type value: int
    44         :rtype: None
    45         """
    46         hash_key = key % self.key_space
    47         self.hash_table[hash_key].update(key, value)
    48 
    49 
    50     def get(self, key):
    51         """
    52         Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key
    53         :type key: int
    54         :rtype: int
    55         """
    56         hash_key = key % self.key_space
    57         return self.hash_table[hash_key].get(key)
    58 
    59 
    60     def remove(self, key):
    61         """
    62         Removes the mapping of the specified value key if this map contains a mapping for the key
    63         :type key: int
    64         :rtype: None
    65         """
    66         hash_key = key % self.key_space
    67         self.hash_table[hash_key].remove(key)
    68 
    69 
    70 # Your MyHashMap object will be instantiated and called as such:
    71 # obj = MyHashMap()
    72 # obj.put(key,value)
    73 # param_2 = obj.get(key)
    74 # obj.remove(key)
    View Code

    128. 哈希函数

    中文English

    在数据结构中,哈希函数是用来将一个字符串(或任何其他类型)转化为小于哈希表大小且大于等于零的整数。一个好的哈希函数可以尽可能少地产生冲突。一种广泛使用的哈希函数算法是使用数值33,假设任何字符串都是基于33的一个大整数,比如:

    hashcode("abcd") = (ascii(a) * 333 + ascii(b) * 332 + ascii(c) *33 + ascii(d)) % HASH_SIZE 

                                  = (97* 333 + 98 * 332 + 99 * 33 +100) % HASH_SIZE

                                  = 3595978 % HASH_SIZE

    其中HASH_SIZE表示哈希表的大小(可以假设一个哈希表就是一个索引0 ~ HASH_SIZE-1的数组)。

    给出一个字符串作为key和一个哈希表的大小,返回这个字符串的哈希值。

    Example

    样例 1:

    输入:  key = "abcd", size = 1000
    输出: 978	
    样例解释:(97 * 33^3 + 98*33^2 + 99*33 + 100*1)%1000 = 978
    

    样例 2:

    输入:  key = "abcd", size = 100
    输出: 78	
    样例解释:(97 * 33^3 + 98*33^2 + 99*33 + 100*1)%100 = 78
    

    Clarification

    对于这个问题,您没有必要设计自己的哈希算法或考虑任何冲突问题,您只需要按照描述实现算法.

     1 class Solution:
     2     """
     3     @param key: A string you should hash
     4     @param HASH_SIZE: An integer
     5     @return: An integer
     6     """
     7     def hashCode(self, key, HASH_SIZE):
     8         # write your code here
     9         ans = 0
    10         for x in key:
    11             ans = (ans *33 + ord(x))%HASH_SIZE
    12             
    13         return ans
    View Code

    129. 重哈希

    中文English

    哈希表容量的大小在一开始是不确定的。如果哈希表存储的元素太多(如超过容量的十分之一),我们应该将哈希表容量扩大一倍,并将所有的哈希值重新安排。假设你有如下一哈希表:

    size=3capacity=4

    [null, 21, 14, null]
           ↓    ↓
           9   null
           ↓
          null
    

    哈希函数为:

    int hashcode(int key, int capacity) {
        return key % capacity;
    }
    

    这里有三个数字9,14,21,其中21和9共享同一个位置因为它们有相同的哈希值1(21 % 4 = 9 % 4 = 1)。我们将它们存储在同一个链表中。

    重建哈希表,将容量扩大一倍,我们将会得到:

    size=3capacity=8

    index:   0    1    2    3     4    5    6   7
    hash : [null, 9, null, null, null, 21, 14, null]
    

    给定一个哈希表,返回重哈希后的哈希表。

    Example

    样例 1

    输入 : [null, 21->9->null, 14->null, null]
    输出 : [null, 9->null, null, null, null, 21->null, 14->null, null]

     1 """
     2 Definition of ListNode
     3 class ListNode(object):
     4 
     5     def __init__(self, val, next=None):
     6         self.val = val
     7         self.next = next
     8 """
     9 class Solution:
    10     """
    11     @param hashTable: A list of The first node of linked list
    12     @return: A list of The first node of linked list which have twice size
    13     """
    14     def rehashing(self, hashTable):
    15         # write your code here
    16         HASH_SIZE = 2 * len(hashTable)
    17         new_hash_table = [None for _ in range(HASH_SIZE)]
    18         
    19         for item in hashTable:
    20             point = item
    21             while point != None:
    22                 self._add_node(new_hash_table, point.val)
    23                 point = point.next
    24                 
    25         return new_hash_table 
    26                 
    27     def _add_node(self, new_hash_table, value):
    28         index = value % (len(new_hash_table))
    29         if new_hash_table[index] == None:
    30             new_hash_table[index] = ListNode(value)
    31         else:
    32             self._add_list_node(new_hash_table[index], value)
    33     
    34     
    35     def _add_list_node(self, node, value):
    36         if node.next != None:
    37             self._add_list_node(node.next, value)
    38         else:
    39             node.next = ListNode(value)
    40         
    View Code

    138. 子数组之和

    中文English

    给定一个整数数组,找到和为零的子数组。你的代码应该返回满足要求的子数组的起始位置和结束位置

    Example

    样例 1:

    输入: [-3, 1, 2, -3, 4]
    输出: [0,2] 或 [1,3]	
    样例解释: 返回任意一段和为0的区间即可。
    

    样例 2:

    输入: [-3, 1, -4, 2, -3, 4]
    输出: [1,5]
    

    Notice

    至少有一个子数组的和为 0

     1 class Solution:
     2     """
     3     @param nums: A list of integers
     4     @return: A list of integers includes the index of the first number and the index of the last number
     5     """
     6     def subarraySum(self, nums):
     7         # write your code here
     8         prefix_hash = {0:-1}
     9         prefix_sum = 0
    10         for index, num in enumerate(nums):
    11             prefix_sum += num
    12             if prefix_sum in prefix_hash.keys():
    13                 return [prefix_hash[prefix_sum]+1, index]
    14             prefix_hash[prefix_sum] = index
    15         
    16         return [-1, -1]
    View Code

    325. 和等于 k 的最长子数组长度

    难度中等

    给定一个数组 nums 和一个目标值 k,找到和等于 k 的最长子数组长度。如果不存在任意一个符合要求的子数组,则返回 0。

    注意:
     nums 数组的总和是一定在 32 位有符号整数范围之内的。

    示例 1:

    输入: nums = [1, -1, 5, -2, 3], k = 3
    输出: 4 
    解释: 子数组 [1, -1, 5, -2] 和等于 3,且长度最长。
    

    示例 2:

    输入: nums = [-2, -1, 2, 1], k = 1
    输出: 2 
    解释: 子数组 [-1, 2] 和等于 1,且长度最长。

    进阶:
    你能使时间复杂度在 O(n) 内完成此题吗?

     1 class Solution:
     2     def maxSubArrayLen(self, nums: List[int], k: int) -> int:
     3         prefix_hash = {0:-1}
     4         prefix_sum = 0
     5         ans = 0
     6         for index, num in enumerate(nums):
     7             prefix_sum += num
     8             if prefix_sum-k in prefix_hash.keys():
     9                 ans = max(index-prefix_hash[prefix_sum-k], ans)
    10                 
    11             if prefix_sum not in prefix_hash.keys():
    12                 prefix_hash[prefix_sum] = index
    13         
    14         return ans
    View Code

    560. 和为K的子数组

    难度中等

    给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。

    示例 1 :

    输入:nums = [1,1,1], k = 2
    输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。
    

    说明 :

    1. 数组的长度为 [1, 20,000]。
    2. 数组中元素的范围是 [-1000, 1000] ,且整数 k 的范围是 [-1e7, 1e7]。
     1 class Solution:
     2     def subarraySum(self, nums: List[int], k: int) -> int:
     3         prefix_hash = {0:1}
     4         prefix_sum = 0
     5         ans = 0
     6         for index, num in enumerate(nums):
     7             prefix_sum += num
     8             if prefix_sum-k in prefix_hash.keys():
     9                 ans += prefix_hash[prefix_sum-k]
    10                 
    11             prefix_hash[prefix_sum] = prefix_hash.setdefault(prefix_sum, 0) + 1
    12         
    13         return ans
    View Code
  • 相关阅读:
    拷贝构造函数与赋值函数的区别
    C++模板(一)
    拷贝构造函数
    memcpy函数
    malloc calloc 和 realloc
    extern关键字
    C中不安全函数
    缓冲区溢出问题
    C++引用
    背包问题专栏(01,完全,多重)
  • 原文地址:https://www.cnblogs.com/dede-0119/p/12517476.html
Copyright © 2020-2023  润新知